From 99af7200fea0b63c67c2e7c842007681e174edb2 Mon Sep 17 00:00:00 2001 From: Al Date: Mon, 8 Jul 2024 17:12:23 +0200 Subject: [PATCH] feat: removing .env files and propagating conventions from python template (#70) * feat: removing .env files and propagating conventions from python template * chore: tmp changing the algokit instance --- .github/workflows/check-python.yaml | 2 +- .../.algokit.toml | 6 ++++- .../{ => .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 +++++++++++++-- .../tests/conftest.py | 24 +++++++---------- .../.algokit.toml | 6 ++++- .../{ => .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 ++++++++++++++-- .../.algokit.toml | 6 ++++- .../{ => .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 +++++++++++++-- .../.algokit.toml | 6 ++++- .../{ => .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 ++++++++++++++-- examples/production_beaker/.algokit.toml | 6 ++++- .../production_beaker/.copier-answers.yml | 10 ------- examples/production_beaker/.env.template | 1 - examples/production_beaker/README.md | 22 +++++++++++++-- examples/production_beaker/tests/conftest.py | 24 +++++++---------- examples/starter_beaker/.algokit.toml | 6 ++++- examples/starter_beaker/.copier-answers.yml | 10 ------- .../starter_beaker/.env.localnet.template | 7 ----- examples/starter_beaker/.env.template | 1 - examples/starter_beaker/.env.testnet.template | 3 --- examples/starter_beaker/README.md | 22 +++++++++++++-- template_content/.algokit.toml.jinja | 6 ++++- .../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 | 26 ++++++++++++++++-- ...use_workspace %}.gitattributes{% endif %}} | 0 .../conftest.py | 24 +++++++---------- tests/test_generators.py | 2 +- tests/test_templates.py | 2 +- 69 files changed, 396 insertions(+), 116 deletions(-) rename examples/generators/production_beaker_smart_contract_python/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/production_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/production_beaker_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_beaker_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_beaker_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_beaker_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_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/production_beaker_smart_contract_python/.env.template rename examples/generators/production_beaker_smart_contract_typescript/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/production_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/production_beaker_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_beaker_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_beaker_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_beaker_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_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/production_beaker_smart_contract_typescript/.env.template rename examples/generators/starter_beaker_smart_contract_python/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/starter_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/starter_beaker_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_beaker_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_beaker_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_beaker_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_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/starter_beaker_smart_contract_python/.env.template rename examples/generators/starter_beaker_smart_contract_typescript/{ => .algokit}/.copier-answers.yml (100%) create mode 100644 examples/generators/starter_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml create mode 100644 examples/generators/starter_beaker_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_beaker_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_beaker_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_beaker_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_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} delete mode 100644 examples/generators/starter_beaker_smart_contract_typescript/.env.template delete mode 100644 examples/production_beaker/.copier-answers.yml delete mode 100644 examples/production_beaker/.env.template delete mode 100644 examples/starter_beaker/.copier-answers.yml delete mode 100644 examples/starter_beaker/.env.localnet.template delete mode 100644 examples/starter_beaker/.env.template delete mode 100644 examples/starter_beaker/.env.testnet.template 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_beaker/.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_beaker/.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 rename template_content/{.gitattributes => {% if not use_workspace %}.gitattributes{% endif %}} (100%) diff --git a/.github/workflows/check-python.yaml b/.github/workflows/check-python.yaml index 23010cb3..a27842d1 100644 --- a/.github/workflows/check-python.yaml +++ b/.github/workflows/check-python.yaml @@ -14,7 +14,7 @@ jobs: run: pipx install poetry - name: Install algokit - run: pipx install algokit + run: pipx install git+https://github.com/algorandfoundation/algokit-cli.git@fix/copier-answers-lookup - name: Run algokit localnet run: algokit localnet start diff --git a/examples/generators/production_beaker_smart_contract_python/.algokit.toml b/examples/generators/production_beaker_smart_contract_python/.algokit.toml index 396a48a0..7a87e357 100644 --- a/examples/generators/production_beaker_smart_contract_python/.algokit.toml +++ b/examples/generators/production_beaker_smart_contract_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker_smart_contract_python' diff --git a/examples/generators/production_beaker_smart_contract_python/.copier-answers.yml b/examples/generators/production_beaker_smart_contract_python/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/production_beaker_smart_contract_python/.copier-answers.yml rename to examples/generators/production_beaker_smart_contract_python/.algokit/.copier-answers.yml diff --git a/examples/generators/production_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml b/examples/generators/production_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 00000000..e1adf73b --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_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_beaker_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 00000000..cfc9f21e --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_smart_contract_python/.env.localnet.template b/examples/generators/production_beaker_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_beaker_smart_contract_python/.env.localnet.template rename to examples/generators/production_beaker_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_beaker_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_beaker_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 00000000..bb9a7873 --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_smart_contract_python/.env.testnet.template b/examples/generators/production_beaker_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_beaker_smart_contract_python/.env.testnet.template rename to examples/generators/production_beaker_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_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/production_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 00000000..e69de29b diff --git a/examples/generators/production_beaker_smart_contract_python/.env.template b/examples/generators/production_beaker_smart_contract_python/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/generators/production_beaker_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_beaker_smart_contract_python/README.md b/examples/generators/production_beaker_smart_contract_python/README.md index bcac42c6..ed42a747 100644 --- a/examples/generators/production_beaker_smart_contract_python/README.md +++ b/examples/generators/production_beaker_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_beaker_smart_contract_python/tests/conftest.py b/examples/generators/production_beaker_smart_contract_python/tests/conftest.py index b0622e78..aec24852 100644 --- a/examples/generators/production_beaker_smart_contract_python/tests/conftest.py +++ b/examples/generators/production_beaker_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_beaker_smart_contract_typescript/.algokit.toml b/examples/generators/production_beaker_smart_contract_typescript/.algokit.toml index b8545aed..f79b6043 100644 --- a/examples/generators/production_beaker_smart_contract_typescript/.algokit.toml +++ b/examples/generators/production_beaker_smart_contract_typescript/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker_smart_contract_typescript' diff --git a/examples/generators/production_beaker_smart_contract_typescript/.copier-answers.yml b/examples/generators/production_beaker_smart_contract_typescript/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/production_beaker_smart_contract_typescript/.copier-answers.yml rename to examples/generators/production_beaker_smart_contract_typescript/.algokit/.copier-answers.yml diff --git a/examples/generators/production_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml b/examples/generators/production_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 00000000..e1adf73b --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_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_beaker_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 00000000..cfc9f21e --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_smart_contract_typescript/.env.localnet.template b/examples/generators/production_beaker_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_beaker_smart_contract_typescript/.env.localnet.template rename to examples/generators/production_beaker_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_beaker_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_beaker_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 00000000..bb9a7873 --- /dev/null +++ b/examples/generators/production_beaker_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_beaker_smart_contract_typescript/.env.testnet.template b/examples/generators/production_beaker_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_beaker_smart_contract_typescript/.env.testnet.template rename to examples/generators/production_beaker_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_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/production_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 00000000..e69de29b diff --git a/examples/generators/production_beaker_smart_contract_typescript/.env.template b/examples/generators/production_beaker_smart_contract_typescript/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/generators/production_beaker_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_beaker_smart_contract_typescript/README.md b/examples/generators/production_beaker_smart_contract_typescript/README.md index 72bd2e37..d9b4d6a9 100644 --- a/examples/generators/production_beaker_smart_contract_typescript/README.md +++ b/examples/generators/production_beaker_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/starter_beaker_smart_contract_python/.algokit.toml b/examples/generators/starter_beaker_smart_contract_python/.algokit.toml index 7d737d1c..132fd16e 100644 --- a/examples/generators/starter_beaker_smart_contract_python/.algokit.toml +++ b/examples/generators/starter_beaker_smart_contract_python/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker_smart_contract_python' diff --git a/examples/generators/starter_beaker_smart_contract_python/.copier-answers.yml b/examples/generators/starter_beaker_smart_contract_python/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/starter_beaker_smart_contract_python/.copier-answers.yml rename to examples/generators/starter_beaker_smart_contract_python/.algokit/.copier-answers.yml diff --git a/examples/generators/starter_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml b/examples/generators/starter_beaker_smart_contract_python/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 00000000..e1adf73b --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_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_beaker_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 00000000..cfc9f21e --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_smart_contract_python/.env.localnet.template b/examples/generators/starter_beaker_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_beaker_smart_contract_python/.env.localnet.template rename to examples/generators/starter_beaker_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_beaker_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_beaker_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 00000000..bb9a7873 --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_smart_contract_python/.env.testnet.template b/examples/generators/starter_beaker_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_beaker_smart_contract_python/.env.testnet.template rename to examples/generators/starter_beaker_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_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/starter_beaker_smart_contract_python/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 00000000..e69de29b diff --git a/examples/generators/starter_beaker_smart_contract_python/.env.template b/examples/generators/starter_beaker_smart_contract_python/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/generators/starter_beaker_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_beaker_smart_contract_python/README.md b/examples/generators/starter_beaker_smart_contract_python/README.md index d07951d3..55087031 100644 --- a/examples/generators/starter_beaker_smart_contract_python/README.md +++ b/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.algokit.toml b/examples/generators/starter_beaker_smart_contract_typescript/.algokit.toml index f6bfbdbd..78783dd2 100644 --- a/examples/generators/starter_beaker_smart_contract_typescript/.algokit.toml +++ b/examples/generators/starter_beaker_smart_contract_typescript/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker_smart_contract_typescript' diff --git a/examples/generators/starter_beaker_smart_contract_typescript/.copier-answers.yml b/examples/generators/starter_beaker_smart_contract_typescript/.algokit/.copier-answers.yml similarity index 100% rename from examples/generators/starter_beaker_smart_contract_typescript/.copier-answers.yml rename to examples/generators/starter_beaker_smart_contract_typescript/.algokit/.copier-answers.yml diff --git a/examples/generators/starter_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml b/examples/generators/starter_beaker_smart_contract_typescript/.algokit/generators/create_env_file/copier.yaml new file mode 100644 index 00000000..e1adf73b --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_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_beaker_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 00000000..cfc9f21e --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.env.localnet.template b/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.env.localnet.template rename to examples/generators/starter_beaker_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_beaker_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_beaker_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 00000000..bb9a7873 --- /dev/null +++ b/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.env.testnet.template b/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.env.testnet.template rename to examples/generators/starter_beaker_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_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} b/examples/generators/starter_beaker_smart_contract_typescript/.algokit/generators/create_env_file/{% if use_generic_env %}.env.j2{% endif %} new file mode 100644 index 00000000..e69de29b diff --git a/examples/generators/starter_beaker_smart_contract_typescript/.env.template b/examples/generators/starter_beaker_smart_contract_typescript/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/generators/starter_beaker_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_beaker_smart_contract_typescript/README.md b/examples/generators/starter_beaker_smart_contract_typescript/README.md index 8132d767..0bbc8682 100644 --- a/examples/generators/starter_beaker_smart_contract_typescript/README.md +++ b/examples/generators/starter_beaker_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/production_beaker/.algokit.toml b/examples/production_beaker/.algokit.toml index a6a2bad7..9fcd49a7 100644 --- a/examples/production_beaker/.algokit.toml +++ b/examples/production_beaker/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker' diff --git a/examples/production_beaker/.copier-answers.yml b/examples/production_beaker/.copier-answers.yml deleted file mode 100644 index 99869a4a..00000000 --- a/examples/production_beaker/.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_beaker - diff --git a/examples/production_beaker/.env.template b/examples/production_beaker/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/production_beaker/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/production_beaker/README.md b/examples/production_beaker/README.md index cc59ed91..e29d3768 100644 --- a/examples/production_beaker/README.md +++ b/examples/production_beaker/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_beaker/tests/conftest.py b/examples/production_beaker/tests/conftest.py index b0622e78..aec24852 100644 --- a/examples/production_beaker/tests/conftest.py +++ b/examples/production_beaker/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_beaker/.algokit.toml b/examples/starter_beaker/.algokit.toml index e1cd14c4..7f82c08a 100644 --- a/examples/starter_beaker/.algokit.toml +++ b/examples/starter_beaker/.algokit.toml @@ -1,10 +1,14 @@ [algokit] min_version = "v2.0.0" -[generate.smart_contract] +[generate.smart-contract] description = "Adds new smart contract to 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_beaker' diff --git a/examples/starter_beaker/.copier-answers.yml b/examples/starter_beaker/.copier-answers.yml deleted file mode 100644 index 7d50ba53..00000000 --- a/examples/starter_beaker/.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_beaker - diff --git a/examples/starter_beaker/.env.localnet.template b/examples/starter_beaker/.env.localnet.template deleted file mode 100644 index fcbf442d..00000000 --- a/examples/starter_beaker/.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_beaker/.env.template b/examples/starter_beaker/.env.template deleted file mode 100644 index 184b3934..00000000 --- a/examples/starter_beaker/.env.template +++ /dev/null @@ -1 +0,0 @@ -# this file should contain environment variables common to all environments/networks diff --git a/examples/starter_beaker/.env.testnet.template b/examples/starter_beaker/.env.testnet.template deleted file mode 100644 index eeea43d7..00000000 --- a/examples/starter_beaker/.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_beaker/README.md b/examples/starter_beaker/README.md index b238c87b..06d158f3 100644 --- a/examples/starter_beaker/README.md +++ b/examples/starter_beaker/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/template_content/.algokit.toml.jinja b/template_content/.algokit.toml.jinja index 909eca01..8dd74310 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] +[generate.smart-contract] description = "Adds new smart contract to 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 00000000..e1adf73b --- /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 00000000..cfc9f21e --- /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_beaker/.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_beaker/.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 00000000..bb9a7873 --- /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_beaker/.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_beaker/.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 00000000..e69de29b 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 6143299e..00000000 --- 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 184b3934..00000000 --- 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 eeea43d7..00000000 --- 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 89f78ce7..07054285 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,29 @@ 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/.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 b0622e78..aec24852 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 9103a82e..bb503bb7 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -116,7 +116,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 aa5e30a4..2dfa162d 100644 --- a/tests/test_templates.py +++ b/tests/test_templates.py @@ -113,7 +113,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)