From f27e111d5140a4142c25d7b6d515db07fd472499 Mon Sep 17 00:00:00 2001 From: Al Date: Mon, 8 Jul 2024 16:20:10 +0200 Subject: [PATCH] feat: removing .env files, adding env-file generator (#31) * feat: refining template, removing env files, adding new env file generator * docs: refining docs * docs: refining docs * chore: apply suggestions from code review Co-authored-by: Neil Campbell * chore: minor tweaks in gitattributes * chore: hiding copier answers file --------- Co-authored-by: Neil Campbell --- .../.algokit.toml | 8 ++++-- .../{ => .algokit}/.copier-answers.yml | 0 .../generators/create_env_file/copier.yaml | 27 +++++++++++++++++++ ....env.{{custom_network_name}}.j2{% endif %} | 7 +++++ ... 'localnet' %}.env.localnet.j2{% endif %}} | 0 ... == 'mainnet' %}.env.mainnet.j2{% endif %} | 3 +++ ...== 'testnet' %}.env.testnet.j2{% endif %}} | 0 ...{% if use_generic_env %}.env.j2{% endif %} | 0 .../.env.template | 1 - .../README.md | 22 +++++++++++++-- .../smart_contracts/README.md | 9 ------- .../tests/conftest.py | 24 +++++++---------- .../.algokit.toml | 8 ++++-- .../{ => .algokit}/.copier-answers.yml | 0 .../generators/create_env_file/copier.yaml | 27 +++++++++++++++++++ ....env.{{custom_network_name}}.j2{% endif %} | 7 +++++ ... 'localnet' %}.env.localnet.j2{% endif %}} | 0 ... == 'mainnet' %}.env.mainnet.j2{% endif %} | 3 +++ ...== 'testnet' %}.env.testnet.j2{% endif %}} | 0 ...{% if use_generic_env %}.env.j2{% endif %} | 0 .../.env.template | 1 - .../README.md | 23 ++++++++++++++-- .../smart_contracts/README.md | 10 ------- .../.algokit.toml | 8 ++++-- .../{ => .algokit}/.copier-answers.yml | 0 .../generators/create_env_file/copier.yaml | 27 +++++++++++++++++++ ....env.{{custom_network_name}}.j2{% endif %} | 7 +++++ ... 'localnet' %}.env.localnet.j2{% endif %}} | 0 ... == 'mainnet' %}.env.mainnet.j2{% endif %} | 3 +++ ...== 'testnet' %}.env.testnet.j2{% endif %}} | 0 ...{% if use_generic_env %}.env.j2{% endif %} | 0 .../.env.template | 1 - .../README.md | 22 +++++++++++++-- .../smart_contracts/README.md | 9 ------- .../.algokit.toml | 8 ++++-- .../{ => .algokit}/.copier-answers.yml | 0 .../generators/create_env_file/copier.yaml | 27 +++++++++++++++++++ ....env.{{custom_network_name}}.j2{% endif %} | 7 +++++ ... 'localnet' %}.env.localnet.j2{% endif %}} | 0 ... == 'mainnet' %}.env.mainnet.j2{% endif %} | 3 +++ ...== 'testnet' %}.env.testnet.j2{% endif %}} | 0 ...{% if use_generic_env %}.env.j2{% endif %} | 0 .../.env.template | 1 - .../README.md | 23 ++++++++++++++-- .../smart_contracts/README.md | 10 ------- examples/production_python/.algokit.toml | 8 ++++-- .../production_python/.copier-answers.yml | 10 ------- examples/production_python/.env.template | 1 - examples/production_python/README.md | 22 +++++++++++++-- .../smart_contracts/README.md | 9 ------- examples/production_python/tests/conftest.py | 24 +++++++---------- examples/starter_python/.algokit.toml | 8 ++++-- examples/starter_python/.copier-answers.yml | 10 ------- .../starter_python/.env.localnet.template | 7 ----- examples/starter_python/.env.template | 1 - examples/starter_python/.env.testnet.template | 3 --- examples/starter_python/README.md | 22 +++++++++++++-- .../starter_python/smart_contracts/README.md | 9 ------- template_content/.algokit.toml.jinja | 8 ++++-- .../generators/create_env_file/copier.yaml | 27 +++++++++++++++++++ ...m_network_name}}.j2{% endif %}{% endraw %} | 7 +++++ ... %}.env.localnet.j2{% endif %}{% endraw %} | 0 ...' %}.env.mainnet.j2{% endif %}{% endraw %} | 3 +++ ...' %}.env.testnet.j2{% endif %}{% endraw %} | 0 ...neric_env %}.env.j2{% endif %}{% endraw %} | 0 .../{{ _copier_conf.answers_file }}.jinja | 0 template_content/.env.localnet.template.jinja | 7 ----- template_content/.env.template | 1 - template_content/.env.testnet.template | 3 --- template_content/README.md.jinja | 25 +++++++++++++++-- .../smart_contracts/README.md.jinja | 12 --------- ...use_workspace %}.gitattributes{% endif %}} | 0 .../conftest.py | 24 +++++++---------- tests/test_generators.py | 2 +- tests/test_templates.py | 2 +- 75 files changed, 401 insertions(+), 190 deletions(-) rename examples/generators/production_python_smart_contract_python/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} rename examples/generators/production_python_smart_contract_python/{.env.localnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}} (100%) create mode 100644 examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} rename examples/generators/production_python_smart_contract_python/{.env.testnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}} (100%) create mode 100644 examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/production_python_smart_contract_python/.env.template delete mode 100644 examples/generators/production_python_smart_contract_python/smart_contracts/README.md rename examples/generators/production_python_smart_contract_typescript/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} rename examples/generators/production_python_smart_contract_typescript/{.env.localnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}} (100%) create mode 100644 examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} rename examples/generators/production_python_smart_contract_typescript/{.env.testnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}} (100%) create mode 100644 examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/production_python_smart_contract_typescript/.env.template delete mode 100644 examples/generators/production_python_smart_contract_typescript/smart_contracts/README.md rename examples/generators/starter_python_smart_contract_python/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} rename examples/generators/starter_python_smart_contract_python/{.env.localnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}} (100%) create mode 100644 examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} rename examples/generators/starter_python_smart_contract_python/{.env.testnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}} (100%) create mode 100644 examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/starter_python_smart_contract_python/.env.template delete mode 100644 examples/generators/starter_python_smart_contract_python/smart_contracts/README.md rename examples/generators/starter_python_smart_contract_typescript/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} rename examples/generators/starter_python_smart_contract_typescript/{.env.localnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}} (100%) create mode 100644 examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} rename examples/generators/starter_python_smart_contract_typescript/{.env.testnet.template => .algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}} (100%) create mode 100644 examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/starter_python_smart_contract_typescript/.env.template delete mode 100644 examples/generators/starter_python_smart_contract_typescript/smart_contracts/README.md delete mode 100644 examples/production_python/.copier-answers.yml delete mode 100644 examples/production_python/.env.template delete mode 100644 examples/production_python/smart_contracts/README.md delete mode 100644 examples/starter_python/.copier-answers.yml delete mode 100644 examples/starter_python/.env.localnet.template delete mode 100644 examples/starter_python/.env.template delete mode 100644 examples/starter_python/.env.testnet.template delete mode 100644 examples/starter_python/smart_contracts/README.md create mode 100644 template_content/.algokit/generators/create_env_file/copier.yaml create mode 100644 template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %}{% endraw %} rename examples/production_python/.env.localnet.template => template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}{% endraw %} (100%) create mode 100644 template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %}{% endraw %} rename examples/production_python/.env.testnet.template => template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}{% endraw %} (100%) create mode 100644 template_content/.algokit/generators/create_env_file/{% raw %}{% if use_generic_env %}.env.j2{% endif %}{% endraw %} rename template_content/{ => .algokit}/{{ _copier_conf.answers_file }}.jinja (100%) delete mode 100644 template_content/.env.localnet.template.jinja delete mode 100644 template_content/.env.template delete mode 100644 template_content/.env.testnet.template delete mode 100644 template_content/smart_contracts/README.md.jinja rename template_content/{.gitattributes => {% if not use_workspace %}.gitattributes{% endif %}} (100%) diff --git a/examples/generators/production_python_smart_contract_python/.algokit.toml b/examples/generators/production_python_smart_contract_python/.algokit.toml index 9afc114..181101f 100644 --- a/examples/generators/production_python_smart_contract_python/.algokit.toml +++ b/examples/generators/production_python_smart_contract_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'production_python_smart_contract_python' diff --git a/examples/generators/production_python_smart_contract_python/.copier-answers.yml b/examples/generators/production_python_smart_contract_python/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/production_python_smart_contract_python/.copier-answers.yml rename to examples/generators/production_python_smart_contract_python/.algokit/.copier-answers.yml diff --git a/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 0000000..e1adf73 --- /dev/null +++ b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml @@ -0,0 +1,27 @@ +_tasks: + - "echo '==== Successfully generated new .env file 🚀 ===='" + +use_generic_env: + type: bool + help: Create generic empty .env file (true) or create a network specific .env.{network_name} file (false). + placeholder: "true" + default: "true" + +target_network: + type: str + help: Name of your target network. + choices: + - mainnet + - testnet + - localnet + - custom + default: "localnet" + when: "{{ not use_generic_env }}" + +custom_network_name: + type: str + help: Name of your custom Algorand network. + placeholder: "custom" + when: "{{ not use_generic_env and target_network == 'custom' }}" + +_templates_suffix: ".j2" diff --git a/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} new file mode 100644 index 0000000..cfc9f21 --- /dev/null +++ b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} @@ -0,0 +1,7 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_TOKEN={YOUR_ALGOD_TOKEN} +ALGOD_SERVER={YOUR_ALGOD_SERVER_URL} +ALGOD_PORT={YOUR_ALGOD_PORT} +INDEXER_TOKEN={YOUR_INDEXER_TOKEN} +INDEXER_SERVER={YOUR_INDEXER_SERVER_URL} +INDEXER_PORT={YOUR_INDEXER_PORT} diff --git a/examples/generators/production_python_smart_contract_python/.env.localnet.template b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} similarity index 100% rename from examples/generators/production_python_smart_contract_python/.env.localnet.template rename to examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} diff --git a/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} new file mode 100644 index 0000000..bb9a787 --- /dev/null +++ b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} @@ -0,0 +1,3 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_SERVER=https://mainnet-api.algonode.cloud +INDEXER_SERVER=https://mainnet-idx.algonode.cloud diff --git a/examples/generators/production_python_smart_contract_python/.env.testnet.template b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} similarity index 100% rename from examples/generators/production_python_smart_contract_python/.env.testnet.template rename to examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} diff --git a/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/production_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 0000000..e69de29 diff --git a/examples/generators/production_python_smart_contract_python/.env.template b/examples/generators/production_python_smart_contract_python/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/generators/production_python_smart_contract_python/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/generators/production_python_smart_contract_python/README.md b/examples/generators/production_python_smart_contract_python/README.md index 3ac8154..7df5b15 100644 --- a/examples/generators/production_python_smart_contract_python/README.md +++ b/examples/generators/production_python_smart_contract_python/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,25 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder.### Continuous Integration / Continuous Deployment (CI/CD) +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file`### Continuous Integration / Continuous Deployment (CI/CD) This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder. diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/README.md b/examples/generators/production_python_smart_contract_python/smart_contracts/README.md deleted file mode 100644 index f765c95..0000000 --- a/examples/generators/production_python_smart_contract_python/smart_contracts/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/examples/generators/production_python_smart_contract_python/tests/conftest.py b/examples/generators/production_python_smart_contract_python/tests/conftest.py index b0622e7..aec2485 100644 --- a/examples/generators/production_python_smart_contract_python/tests/conftest.py +++ b/examples/generators/production_python_smart_contract_python/tests/conftest.py @@ -1,32 +1,26 @@ -from pathlib import Path - import pytest from algokit_utils import ( get_algod_client, + get_default_localnet_config, get_indexer_client, - is_localnet, ) from algosdk.v2client.algod import AlgodClient from algosdk.v2client.indexer import IndexerClient -from dotenv import load_dotenv - -@pytest.fixture(autouse=True, scope="session") -def environment_fixture() -> None: - env_path = Path(__file__).parent.parent / ".env.localnet" - load_dotenv(env_path) +# Uncomment if you want to load network specific or generic .env file +# @pytest.fixture(autouse=True, scope="session") +# def environment_fixture() -> None: +# env_path = Path(__file__).parent.parent / ".env" +# load_dotenv(env_path) @pytest.fixture(scope="session") def algod_client() -> AlgodClient: - client = get_algod_client() - - # you can remove this assertion to test on other networks, - # included here to prevent accidentally running against other networks - assert is_localnet(client) + # by default we are using localnet algod + client = get_algod_client(get_default_localnet_config("algod")) return client @pytest.fixture(scope="session") def indexer_client() -> IndexerClient: - return get_indexer_client() + return get_indexer_client(get_default_localnet_config("indexer")) diff --git a/examples/generators/production_python_smart_contract_typescript/.algokit.toml b/examples/generators/production_python_smart_contract_typescript/.algokit.toml index 08ffaf7..be94726 100644 --- a/examples/generators/production_python_smart_contract_typescript/.algokit.toml +++ b/examples/generators/production_python_smart_contract_typescript/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'production_python_smart_contract_typescript' diff --git a/examples/generators/production_python_smart_contract_typescript/.copier-answers.yml b/examples/generators/production_python_smart_contract_typescript/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/production_python_smart_contract_typescript/.copier-answers.yml rename to examples/generators/production_python_smart_contract_typescript/.algokit/.copier-answers.yml diff --git a/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 0000000..e1adf73 --- /dev/null +++ b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml @@ -0,0 +1,27 @@ +_tasks: + - "echo '==== Successfully generated new .env file 🚀 ===='" + +use_generic_env: + type: bool + help: Create generic empty .env file (true) or create a network specific .env.{network_name} file (false). + placeholder: "true" + default: "true" + +target_network: + type: str + help: Name of your target network. + choices: + - mainnet + - testnet + - localnet + - custom + default: "localnet" + when: "{{ not use_generic_env }}" + +custom_network_name: + type: str + help: Name of your custom Algorand network. + placeholder: "custom" + when: "{{ not use_generic_env and target_network == 'custom' }}" + +_templates_suffix: ".j2" diff --git a/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} new file mode 100644 index 0000000..cfc9f21 --- /dev/null +++ b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} @@ -0,0 +1,7 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_TOKEN={YOUR_ALGOD_TOKEN} +ALGOD_SERVER={YOUR_ALGOD_SERVER_URL} +ALGOD_PORT={YOUR_ALGOD_PORT} +INDEXER_TOKEN={YOUR_INDEXER_TOKEN} +INDEXER_SERVER={YOUR_INDEXER_SERVER_URL} +INDEXER_PORT={YOUR_INDEXER_PORT} diff --git a/examples/generators/production_python_smart_contract_typescript/.env.localnet.template b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} similarity index 100% rename from examples/generators/production_python_smart_contract_typescript/.env.localnet.template rename to examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} diff --git a/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} new file mode 100644 index 0000000..bb9a787 --- /dev/null +++ b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} @@ -0,0 +1,3 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_SERVER=https://mainnet-api.algonode.cloud +INDEXER_SERVER=https://mainnet-idx.algonode.cloud diff --git a/examples/generators/production_python_smart_contract_typescript/.env.testnet.template b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} similarity index 100% rename from examples/generators/production_python_smart_contract_typescript/.env.testnet.template rename to examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} diff --git a/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/production_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 0000000..e69de29 diff --git a/examples/generators/production_python_smart_contract_typescript/.env.template b/examples/generators/production_python_smart_contract_typescript/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/generators/production_python_smart_contract_typescript/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/generators/production_python_smart_contract_typescript/README.md b/examples/generators/production_python_smart_contract_typescript/README.md index f1994e5..469abaa 100644 --- a/examples/generators/production_python_smart_contract_typescript/README.md +++ b/examples/generators/production_python_smart_contract_typescript/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,26 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder.### Continuous Integration / Continuous Deployment (CI/CD) +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy-config.ts`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. +4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file`### Continuous Integration / Continuous Deployment (CI/CD) This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder. diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/README.md b/examples/generators/production_python_smart_contract_typescript/smart_contracts/README.md deleted file mode 100644 index e97ba8b..0000000 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy-config.ts`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. -4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/examples/generators/starter_python_smart_contract_python/.algokit.toml b/examples/generators/starter_python_smart_contract_python/.algokit.toml index 2576c3c..bdb2685 100644 --- a/examples/generators/starter_python_smart_contract_python/.algokit.toml +++ b/examples/generators/starter_python_smart_contract_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'starter_python_smart_contract_python' diff --git a/examples/generators/starter_python_smart_contract_python/.copier-answers.yml b/examples/generators/starter_python_smart_contract_python/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/starter_python_smart_contract_python/.copier-answers.yml rename to examples/generators/starter_python_smart_contract_python/.algokit/.copier-answers.yml diff --git a/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 0000000..e1adf73 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/copier.yaml @@ -0,0 +1,27 @@ +_tasks: + - "echo '==== Successfully generated new .env file 🚀 ===='" + +use_generic_env: + type: bool + help: Create generic empty .env file (true) or create a network specific .env.{network_name} file (false). + placeholder: "true" + default: "true" + +target_network: + type: str + help: Name of your target network. + choices: + - mainnet + - testnet + - localnet + - custom + default: "localnet" + when: "{{ not use_generic_env }}" + +custom_network_name: + type: str + help: Name of your custom Algorand network. + placeholder: "custom" + when: "{{ not use_generic_env and target_network == 'custom' }}" + +_templates_suffix: ".j2" diff --git a/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} new file mode 100644 index 0000000..cfc9f21 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} @@ -0,0 +1,7 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_TOKEN={YOUR_ALGOD_TOKEN} +ALGOD_SERVER={YOUR_ALGOD_SERVER_URL} +ALGOD_PORT={YOUR_ALGOD_PORT} +INDEXER_TOKEN={YOUR_INDEXER_TOKEN} +INDEXER_SERVER={YOUR_INDEXER_SERVER_URL} +INDEXER_PORT={YOUR_INDEXER_PORT} diff --git a/examples/generators/starter_python_smart_contract_python/.env.localnet.template b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} similarity index 100% rename from examples/generators/starter_python_smart_contract_python/.env.localnet.template rename to examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} diff --git a/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} new file mode 100644 index 0000000..bb9a787 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} @@ -0,0 +1,3 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_SERVER=https://mainnet-api.algonode.cloud +INDEXER_SERVER=https://mainnet-idx.algonode.cloud diff --git a/examples/generators/starter_python_smart_contract_python/.env.testnet.template b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} similarity index 100% rename from examples/generators/starter_python_smart_contract_python/.env.testnet.template rename to examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} diff --git a/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/starter_python_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 0000000..e69de29 diff --git a/examples/generators/starter_python_smart_contract_python/.env.template b/examples/generators/starter_python_smart_contract_python/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/generators/starter_python_smart_contract_python/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/generators/starter_python_smart_contract_python/README.md b/examples/generators/starter_python_smart_contract_python/README.md index c1a3be3..0a7ee5f 100644 --- a/examples/generators/starter_python_smart_contract_python/README.md +++ b/examples/generators/starter_python_smart_contract_python/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,25 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder. +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file` # Tools diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/README.md b/examples/generators/starter_python_smart_contract_python/smart_contracts/README.md deleted file mode 100644 index f765c95..0000000 --- a/examples/generators/starter_python_smart_contract_python/smart_contracts/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/examples/generators/starter_python_smart_contract_typescript/.algokit.toml b/examples/generators/starter_python_smart_contract_typescript/.algokit.toml index 8ebbc1b..da1bb1f 100644 --- a/examples/generators/starter_python_smart_contract_typescript/.algokit.toml +++ b/examples/generators/starter_python_smart_contract_typescript/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'starter_python_smart_contract_typescript' diff --git a/examples/generators/starter_python_smart_contract_typescript/.copier-answers.yml b/examples/generators/starter_python_smart_contract_typescript/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/starter_python_smart_contract_typescript/.copier-answers.yml rename to examples/generators/starter_python_smart_contract_typescript/.algokit/.copier-answers.yml diff --git a/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 0000000..e1adf73 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml @@ -0,0 +1,27 @@ +_tasks: + - "echo '==== Successfully generated new .env file 🚀 ===='" + +use_generic_env: + type: bool + help: Create generic empty .env file (true) or create a network specific .env.{network_name} file (false). + placeholder: "true" + default: "true" + +target_network: + type: str + help: Name of your target network. + choices: + - mainnet + - testnet + - localnet + - custom + default: "localnet" + when: "{{ not use_generic_env }}" + +custom_network_name: + type: str + help: Name of your custom Algorand network. + placeholder: "custom" + when: "{{ not use_generic_env and target_network == 'custom' }}" + +_templates_suffix: ".j2" diff --git a/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} new file mode 100644 index 0000000..cfc9f21 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %} @@ -0,0 +1,7 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_TOKEN={YOUR_ALGOD_TOKEN} +ALGOD_SERVER={YOUR_ALGOD_SERVER_URL} +ALGOD_PORT={YOUR_ALGOD_PORT} +INDEXER_TOKEN={YOUR_INDEXER_TOKEN} +INDEXER_SERVER={YOUR_INDEXER_SERVER_URL} +INDEXER_PORT={YOUR_INDEXER_PORT} diff --git a/examples/generators/starter_python_smart_contract_typescript/.env.localnet.template b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} similarity index 100% rename from examples/generators/starter_python_smart_contract_typescript/.env.localnet.template rename to examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %} diff --git a/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} new file mode 100644 index 0000000..bb9a787 --- /dev/null +++ b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %} @@ -0,0 +1,3 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_SERVER=https://mainnet-api.algonode.cloud +INDEXER_SERVER=https://mainnet-idx.algonode.cloud diff --git a/examples/generators/starter_python_smart_contract_typescript/.env.testnet.template b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} similarity index 100% rename from examples/generators/starter_python_smart_contract_typescript/.env.testnet.template rename to examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %} diff --git a/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/starter_python_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 0000000..e69de29 diff --git a/examples/generators/starter_python_smart_contract_typescript/.env.template b/examples/generators/starter_python_smart_contract_typescript/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/generators/starter_python_smart_contract_typescript/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/generators/starter_python_smart_contract_typescript/README.md b/examples/generators/starter_python_smart_contract_typescript/README.md index 384a8b6..2617064 100644 --- a/examples/generators/starter_python_smart_contract_typescript/README.md +++ b/examples/generators/starter_python_smart_contract_typescript/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,26 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder. +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy-config.ts`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. +4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file` # Tools diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/README.md b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/README.md deleted file mode 100644 index e97ba8b..0000000 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy-config.ts`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. -4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/examples/production_python/.algokit.toml b/examples/production_python/.algokit.toml index 8f08db0..6093afd 100644 --- a/examples/production_python/.algokit.toml +++ b/examples/production_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'production_python' diff --git a/examples/production_python/.copier-answers.yml b/examples/production_python/.copier-answers.yml deleted file mode 100644 index f9e960d..0000000 --- a/examples/production_python/.copier-answers.yml +++ /dev/null @@ -1,10 +0,0 @@ -# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: -_src_path: -author_email: None -author_name: None -contract_name: hello_world -deployment_language: python -preset_name: production -project_name: production_python - diff --git a/examples/production_python/.env.template b/examples/production_python/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/production_python/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/production_python/README.md b/examples/production_python/README.md index 061dbf0..9ebcc7c 100644 --- a/examples/production_python/README.md +++ b/examples/production_python/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,25 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder.### Continuous Integration / Continuous Deployment (CI/CD) +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file`### Continuous Integration / Continuous Deployment (CI/CD) This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder. diff --git a/examples/production_python/smart_contracts/README.md b/examples/production_python/smart_contracts/README.md deleted file mode 100644 index f765c95..0000000 --- a/examples/production_python/smart_contracts/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/examples/production_python/tests/conftest.py b/examples/production_python/tests/conftest.py index b0622e7..aec2485 100644 --- a/examples/production_python/tests/conftest.py +++ b/examples/production_python/tests/conftest.py @@ -1,32 +1,26 @@ -from pathlib import Path - import pytest from algokit_utils import ( get_algod_client, + get_default_localnet_config, get_indexer_client, - is_localnet, ) from algosdk.v2client.algod import AlgodClient from algosdk.v2client.indexer import IndexerClient -from dotenv import load_dotenv - -@pytest.fixture(autouse=True, scope="session") -def environment_fixture() -> None: - env_path = Path(__file__).parent.parent / ".env.localnet" - load_dotenv(env_path) +# Uncomment if you want to load network specific or generic .env file +# @pytest.fixture(autouse=True, scope="session") +# def environment_fixture() -> None: +# env_path = Path(__file__).parent.parent / ".env" +# load_dotenv(env_path) @pytest.fixture(scope="session") def algod_client() -> AlgodClient: - client = get_algod_client() - - # you can remove this assertion to test on other networks, - # included here to prevent accidentally running against other networks - assert is_localnet(client) + # by default we are using localnet algod + client = get_algod_client(get_default_localnet_config("algod")) return client @pytest.fixture(scope="session") def indexer_client() -> IndexerClient: - return get_indexer_client() + return get_indexer_client(get_default_localnet_config("indexer")) diff --git a/examples/starter_python/.algokit.toml b/examples/starter_python/.algokit.toml index 1d9a006..ead1544 100644 --- a/examples/starter_python/.algokit.toml +++ b/examples/starter_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = 'starter_python' diff --git a/examples/starter_python/.copier-answers.yml b/examples/starter_python/.copier-answers.yml deleted file mode 100644 index dac2839..0000000 --- a/examples/starter_python/.copier-answers.yml +++ /dev/null @@ -1,10 +0,0 @@ -# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: -_src_path: -author_email: None -author_name: None -contract_name: hello_world -deployment_language: python -preset_name: starter -project_name: starter_python - diff --git a/examples/starter_python/.env.localnet.template b/examples/starter_python/.env.localnet.template deleted file mode 100644 index fcbf442..0000000 --- a/examples/starter_python/.env.localnet.template +++ /dev/null @@ -1,7 +0,0 @@ -# this file should contain environment variables specific to algokit localnet -ALGOD_TOKEN=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -ALGOD_SERVER=http://localhost -ALGOD_PORT=4001 -INDEXER_TOKEN=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -INDEXER_SERVER=http://localhost -INDEXER_PORT=8980 diff --git a/examples/starter_python/.env.template b/examples/starter_python/.env.template deleted file mode 100644 index 184b393..0000000 --- a/examples/starter_python/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/starter_python/.env.testnet.template b/examples/starter_python/.env.testnet.template deleted file mode 100644 index eeea43d..0000000 --- a/examples/starter_python/.env.testnet.template +++ /dev/null @@ -1,3 +0,0 @@ -# this file contains algorand network settings for interacting with testnet via algonode -ALGOD_SERVER=https://testnet-api.algonode.cloud -INDEXER_SERVER=https://testnet-idx.algonode.cloud diff --git a/examples/starter_python/README.md b/examples/starter_python/README.md index 8750537..6093b0b 100644 --- a/examples/starter_python/README.md +++ b/examples/starter_python/README.md @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,25 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder. +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file` # Tools diff --git a/examples/starter_python/smart_contracts/README.md b/examples/starter_python/smart_contracts/README.md deleted file mode 100644 index f765c95..0000000 --- a/examples/starter_python/smart_contracts/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/template_content/.algokit.toml.jinja b/template_content/.algokit.toml.jinja index 7efab4b..45e4cac 100644 --- a/template_content/.algokit.toml.jinja +++ b/template_content/.algokit.toml.jinja @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] -description = "Adds new smart contract to existing project" +[generate.smart-contract] +description = "Generate a new smart contract for existing project" path = ".algokit/generators/create_contract" +[generate.env-file] +description = "Generate a new generic or Algorand network specific .env file" +path = ".algokit/generators/create_env_file" + [project] type = 'contract' name = '{{ project_name }}' diff --git a/template_content/.algokit/generators/create_env_file/copier.yaml b/template_content/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 0000000..e1adf73 --- /dev/null +++ b/template_content/.algokit/generators/create_env_file/copier.yaml @@ -0,0 +1,27 @@ +_tasks: + - "echo '==== Successfully generated new .env file 🚀 ===='" + +use_generic_env: + type: bool + help: Create generic empty .env file (true) or create a network specific .env.{network_name} file (false). + placeholder: "true" + default: "true" + +target_network: + type: str + help: Name of your target network. + choices: + - mainnet + - testnet + - localnet + - custom + default: "localnet" + when: "{{ not use_generic_env }}" + +custom_network_name: + type: str + help: Name of your custom Algorand network. + placeholder: "custom" + when: "{{ not use_generic_env and target_network == 'custom' }}" + +_templates_suffix: ".j2" diff --git a/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %}{% endraw %} b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %}{% endraw %} new file mode 100644 index 0000000..cfc9f21 --- /dev/null +++ b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'custom' %}.env.{{custom_network_name}}.j2{% endif %}{% endraw %} @@ -0,0 +1,7 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_TOKEN={YOUR_ALGOD_TOKEN} +ALGOD_SERVER={YOUR_ALGOD_SERVER_URL} +ALGOD_PORT={YOUR_ALGOD_PORT} +INDEXER_TOKEN={YOUR_INDEXER_TOKEN} +INDEXER_SERVER={YOUR_INDEXER_SERVER_URL} +INDEXER_PORT={YOUR_INDEXER_PORT} diff --git a/examples/production_python/.env.localnet.template b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}{% endraw %} similarity index 100% rename from examples/production_python/.env.localnet.template rename to template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'localnet' %}.env.localnet.j2{% endif %}{% endraw %} diff --git a/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %}{% endraw %} b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %}{% endraw %} new file mode 100644 index 0000000..bb9a787 --- /dev/null +++ b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'mainnet' %}.env.mainnet.j2{% endif %}{% endraw %} @@ -0,0 +1,3 @@ +# this file contains algorand network settings for interacting with testnet via algonode +ALGOD_SERVER=https://mainnet-api.algonode.cloud +INDEXER_SERVER=https://mainnet-idx.algonode.cloud diff --git a/examples/production_python/.env.testnet.template b/template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}{% endraw %} similarity index 100% rename from examples/production_python/.env.testnet.template rename to template_content/.algokit/generators/create_env_file/{% raw %}{% if not use_generic_env and target_network == 'testnet' %}.env.testnet.j2{% endif %}{% endraw %} diff --git a/template_content/.algokit/generators/create_env_file/{% raw %}{% if use_generic_env %}.env.j2{% endif %}{% endraw %} b/template_content/.algokit/generators/create_env_file/{% raw %}{% if use_generic_env %}.env.j2{% endif %}{% endraw %} new file mode 100644 index 0000000..e69de29 diff --git a/template_content/{{ _copier_conf.answers_file }}.jinja b/template_content/.algokit/{{ _copier_conf.answers_file }}.jinja similarity index 100% rename from template_content/{{ _copier_conf.answers_file }}.jinja rename to template_content/.algokit/{{ _copier_conf.answers_file }}.jinja diff --git a/template_content/.env.localnet.template.jinja b/template_content/.env.localnet.template.jinja deleted file mode 100644 index 6143299..0000000 --- a/template_content/.env.localnet.template.jinja +++ /dev/null @@ -1,7 +0,0 @@ -# this file should contain environment variables specific to algokit localnet -ALGOD_TOKEN={{ algod_token }} -ALGOD_SERVER={{ algod_server }} -ALGOD_PORT={{ algod_port }} -INDEXER_TOKEN={{ indexer_token }} -INDEXER_SERVER={{ indexer_server }} -INDEXER_PORT={{ indexer_port }} diff --git a/template_content/.env.template b/template_content/.env.template deleted file mode 100644 index 184b393..0000000 --- a/template_content/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/template_content/.env.testnet.template b/template_content/.env.testnet.template deleted file mode 100644 index eeea43d..0000000 --- a/template_content/.env.testnet.template +++ /dev/null @@ -1,3 +0,0 @@ -# this file contains algorand network settings for interacting with testnet via algonode -ALGOD_SERVER=https://testnet-api.algonode.cloud -INDEXER_SERVER=https://testnet-idx.algonode.cloud diff --git a/template_content/README.md.jinja b/template_content/README.md.jinja index ffc4794..d2fbe84 100644 --- a/template_content/README.md.jinja +++ b/template_content/README.md.jinja @@ -28,7 +28,7 @@ Run the following commands within the project folder: - **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. - **Setup Project**: Execute `algokit project bootstrap all` to: - Install dependencies and setup a Python virtual environment in `.venv`. - - Copy `.env.template` to `.env`. + - Configure '.env' files if needed (see [AlgoKit Generators](#algokit-generators)). - **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. ### Development Workflow @@ -58,7 +58,28 @@ While primarily optimized for VS Code, JetBrains IDEs are supported: ## AlgoKit Workspaces and Project Management This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. -> For guidance on `smart_contracts` folder and adding new contracts to the project please see [README](smart_contracts/README.md) on the respective folder. +## AlgoKit Generators + +This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. + +### Generate Smart Contract + +By default the template creates a single `HelloWorld` contract under {{ contract_name }} folder in the `smart_contracts` directory. To add a new contract: + +1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. +2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in {% if deployment_language == 'python' %}`deploy_config.py`{% elif deployment_language == 'typescript' %}`deploy-config.ts`{% endif %}file. +3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. +{%- if deployment_language == 'typescript' %} +4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. +{%- endif %} + +> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. + +### Generate '.env' files + +By default the template instance would not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. + +To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file` {%- if use_github_actions -%} ### Continuous Integration / Continuous Deployment (CI/CD) diff --git a/template_content/smart_contracts/README.md.jinja b/template_content/smart_contracts/README.md.jinja deleted file mode 100644 index 99fa275..0000000 --- a/template_content/smart_contracts/README.md.jinja +++ /dev/null @@ -1,12 +0,0 @@ -## How to add new smart contracts? - -By the default the template creates a single `HelloWorld` contract under {{ contract_name }} folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder under `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in {% if deployment_language == 'python' %}`deploy_config.py`{% elif deployment_language == 'typescript' %}`deploy-config.ts`{% endif %}file. -3. `config.py` file will automatically build all contracts under `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. -{%- if deployment_language == 'typescript' %} -4. Since you are generating a TypeScript client, you also need to reference your contract deployment logic in `index.ts` file. However, similar to config.py, by default, `index.ts` will auto import all TypeScript deployment files under `smart_contracts` directory. If you want to manually import specific contracts, modify the default code provided by the template in `index.ts` file. -{%- endif %} - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. Default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. diff --git a/template_content/.gitattributes b/template_content/{% if not use_workspace %}.gitattributes{% endif %} similarity index 100% rename from template_content/.gitattributes rename to template_content/{% if not use_workspace %}.gitattributes{% endif %} diff --git a/template_content/{% if use_python_pytest %}tests{% endif %}/conftest.py b/template_content/{% if use_python_pytest %}tests{% endif %}/conftest.py index b0622e7..aec2485 100644 --- a/template_content/{% if use_python_pytest %}tests{% endif %}/conftest.py +++ b/template_content/{% if use_python_pytest %}tests{% endif %}/conftest.py @@ -1,32 +1,26 @@ -from pathlib import Path - import pytest from algokit_utils import ( get_algod_client, + get_default_localnet_config, get_indexer_client, - is_localnet, ) from algosdk.v2client.algod import AlgodClient from algosdk.v2client.indexer import IndexerClient -from dotenv import load_dotenv - -@pytest.fixture(autouse=True, scope="session") -def environment_fixture() -> None: - env_path = Path(__file__).parent.parent / ".env.localnet" - load_dotenv(env_path) +# Uncomment if you want to load network specific or generic .env file +# @pytest.fixture(autouse=True, scope="session") +# def environment_fixture() -> None: +# env_path = Path(__file__).parent.parent / ".env" +# load_dotenv(env_path) @pytest.fixture(scope="session") def algod_client() -> AlgodClient: - client = get_algod_client() - - # you can remove this assertion to test on other networks, - # included here to prevent accidentally running against other networks - assert is_localnet(client) + # by default we are using localnet algod + client = get_algod_client(get_default_localnet_config("algod")) return client @pytest.fixture(scope="session") def indexer_client() -> IndexerClient: - return get_indexer_client() + return get_indexer_client(get_default_localnet_config("indexer")) diff --git a/tests/test_generators.py b/tests/test_generators.py index 6db0d3a..36d15b2 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -117,7 +117,7 @@ def check_codebase(working_dir: Path, test_name: str) -> subprocess.CompletedPro copy_to = working_dir / generated_folder / test_name # if successful, normalize .copier-answers.yml to make observing diffs easier - copier_answers = Path(copy_to / ".copier-answers.yml") + copier_answers = Path(copy_to / ".algokit" / ".copier-answers.yml") content = copier_answers.read_text("utf-8") content = commit_pattern.sub("_commit: ", content) content = src_path_pattern.sub("_src_path: ", content) diff --git a/tests/test_templates.py b/tests/test_templates.py index 4b00aa6..b3be18a 100644 --- a/tests/test_templates.py +++ b/tests/test_templates.py @@ -114,7 +114,7 @@ def run_init( if result.returncode: return result # if successful, normalize .copier-answers.yml to make observing diffs easier - copier_answers = Path(copy_to / ".copier-answers.yml") + copier_answers = Path(copy_to / ".algokit" / ".copier-answers.yml") content = copier_answers.read_text("utf-8") content = commit_pattern.sub("_commit: ", content) content = src_path_pattern.sub("_src_path: ", content)