Skip to content

Commit

Permalink
feat: adding default algorand network configs to use when no .env.{ne…
Browse files Browse the repository at this point in the history
…twork} found (#533)

* feat: adding default algorand network configs to use when no .env.{network} found

* chore: addressing pr comments

* docs: expanding docs

* chore: pip audit

* docs: tweaking path to copier-answers

* chore: minor tweak to account for answers being inside .algokit folder
  • Loading branch information
aorumbayev authored Jul 8, 2024
1 parent 9fa5005 commit a726756
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/features/init.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ If you want to create a community template, you can use the [AlgoKit guidelines

Answers to specific template prompts can be provided with the `--answer {key} {value}` option, which can be used multiple times for each prompt. Quotes can be used for values with spaces e.g. `--answer author_name "Algorand Foundation"`.

To find out the key for a specific answer you can either look at `.copier-answers.yml` in the root folder of a project created via `algokit init` or in the `copier.yaml` file of a template repo e.g. for the [beaker template](https://github.com/algorandfoundation/algokit-beaker-default-template/blob/main/copier.yaml).
To find out the key for a specific answer you can either look at `.algokit/.copier-answers.yml` in the root folder of a project created via `algokit init` or in the `copier.yaml` file of a template repo e.g. for the [beaker template](https://github.com/algorandfoundation/algokit-beaker-default-template/blob/main/copier.yaml).

## Non-interactive project initialization

Expand Down
26 changes: 26 additions & 0 deletions docs/features/project/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,32 @@ The logic for loading environment variables is as follows:
- If a `.env` file exists, the environment variables contained in it are loaded first.
- If a `.env.[network_name]` file exists, the environment variables in it are loaded, overriding any previously loaded values from the `.env` file for the same variables.

### Default Network Configurations

The `deploy` command assumes default configurations for `mainnet`, `localnet`, and `testnet` environments. If you're deploying to one of these networks and haven't provided specific environment variables, AlgoKit will use these default values:

- **Localnet**:

- `ALGOD_TOKEN`: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- `ALGOD_SERVER`: "http://localhost"
- `ALGOD_PORT`: "4001"
- `INDEXER_TOKEN`: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- `INDEXER_SERVER`: "http://localhost"
- `INDEXER_PORT`: "8980"

- **Mainnet**:

- `ALGOD_SERVER`: "https://mainnet-api.algonode.cloud"
- `INDEXER_SERVER`: "https://mainnet-idx.algonode.cloud"

- **Testnet**:
- `ALGOD_SERVER`: "https://testnet-api.algonode.cloud"
- `INDEXER_SERVER`: "https://testnet-idx.algonode.cloud"

These default values are used when no specific `.env.[network_name]` file is present and the corresponding environment variables are not set. This feature simplifies the deployment process for these common networks, reducing the need for manual configuration in many cases.

If you need to override these defaults or add additional configuration for these networks, you can still do so by creating the appropriate `.env.[network_name]` file or setting the environment variables explicitly or via generic `.env` file.

## AlgoKit Configuration File

AlgoKit uses a configuration file called `.algokit.toml` in the root of your project. The configuration file can be created using the `algokit init` command. This file will define the deployment commands for the various network environments that you want to target.
Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/algokit/cli/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,11 @@ def init_command( # noqa: PLR0913, C901, PLR0915

from algokit.core.init import populate_default_answers

answers_file = project_path / ".algokit" / ".copier-answers.yml"
with Worker(
src_path=template.url,
dst_path=project_path,
answers_file=answers_file if answers_file.exists() else None,
data=answers_dict,
quiet=True,
vcs_ref=template.branch or template.commit,
Expand Down
2 changes: 1 addition & 1 deletion src/algokit/cli/project/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def _execute_deploy_command( # noqa: PLR0913
else:
msg = (
f"Deploy command for '{environment_name}' is not specified in '{ALGOKIT_CONFIG}' file, "
"and no generic command."
"and no generic command available."
)
raise click.ClickException(msg)
resolved_command = resolve_command_path(config.command)
Expand Down
51 changes: 49 additions & 2 deletions src/algokit/core/project/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,55 @@

import click
import dotenv
from algokit_utils import get_algonode_config

from algokit.core.conf import ALGOKIT_CONFIG, get_algokit_config
from algokit.core.sandbox import (
DEFAULT_ALGOD_PORT,
DEFAULT_ALGOD_SERVER,
DEFAULT_ALGOD_TOKEN,
DEFAULT_INDEXER_PORT,
DEFAULT_INDEXER_SERVER,
DEFAULT_INDEXER_TOKEN,
)
from algokit.core.utils import load_env_file, split_command_string

logger = logging.getLogger(__name__)


class _KnownEnvironments:
LOCALNET = "localnet"
MAINNET = "mainnet"
TESTNET = "testnet"


DEFAULT_MAINNET_ALGOD_SERVER = get_algonode_config("mainnet", config="algod", token="").server
DEFAULT_TESTNET_ALGOD_SERVER = get_algonode_config("testnet", config="algod", token="").server
DEFAULT_MAINNET_INDEXER_SERVER = get_algonode_config("mainnet", config="indexer", token="").server
DEFAULT_TESTNET_INDEXER_SERVER = get_algonode_config("testnet", config="indexer", token="").server


_ENVIRONMENT_CONFIG: dict[str, dict[str, str | None]] = {
_KnownEnvironments.LOCALNET: {
# this file should contain environment variables specific to algokit localnet
"ALGOD_TOKEN": str(DEFAULT_ALGOD_TOKEN),
"ALGOD_SERVER": str(DEFAULT_ALGOD_SERVER),
"ALGOD_PORT": str(DEFAULT_ALGOD_PORT),
"INDEXER_TOKEN": str(DEFAULT_INDEXER_TOKEN),
"INDEXER_SERVER": str(DEFAULT_INDEXER_SERVER),
"INDEXER_PORT": str(DEFAULT_INDEXER_PORT),
},
_KnownEnvironments.MAINNET: {
"ALGOD_SERVER": DEFAULT_MAINNET_ALGOD_SERVER,
"INDEXER_SERVER": DEFAULT_MAINNET_INDEXER_SERVER,
},
_KnownEnvironments.TESTNET: {
"ALGOD_SERVER": DEFAULT_TESTNET_ALGOD_SERVER,
"INDEXER_SERVER": DEFAULT_TESTNET_INDEXER_SERVER,
},
}


def load_deploy_env_files(name: str | None, project_dir: Path) -> dict[str, str | None]:
"""
Load the deploy configuration for the given network.
Expand All @@ -20,9 +62,14 @@ def load_deploy_env_files(name: str | None, project_dir: Path) -> dict[str, str
result = load_env_file(project_dir)
if name is not None:
specific_env_path = project_dir / f".env.{name}"
if not specific_env_path.exists():
if specific_env_path.exists():
result |= dotenv.dotenv_values(specific_env_path, verbose=True)

if name in _ENVIRONMENT_CONFIG:
logger.debug(f"Using default environment config for algod and indexer for network {name}")
result |= _ENVIRONMENT_CONFIG[name]
elif not specific_env_path.exists():
raise click.ClickException(f"No such file: {specific_env_path}")
result |= dotenv.dotenv_values(specific_env_path, verbose=True)
return result


Expand Down
2 changes: 2 additions & 0 deletions src/algokit/core/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ def check_docker_compose_for_new_image_versions(self) -> None:


DEFAULT_ALGOD_SERVER = "http://localhost"
DEFAULT_INDEXER_SERVER = "http://localhost"
DEFAULT_ALGOD_TOKEN = "a" * 64
DEFAULT_INDEXER_TOKEN = "a" * 64
DEFAULT_ALGOD_PORT = 4001
DEFAULT_INDEXER_PORT = 8980
DEFAULT_WAIT_FOR_ALGOD = 60
Expand Down
4 changes: 2 additions & 2 deletions tests/project/deploy/test_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,15 @@ def test_command_bad_exit_code(proc_mock: ProcMock, tmp_path: Path, which_mock:

def test_algokit_env_name_missing(tmp_path_factory: TempPathFactory, which_mock: WhichMock) -> None:
config_with_override = """
[project.deploy.localnet]
[project.deploy.customnet]
command = "command_a"
""".strip()
cwd = tmp_path_factory.mktemp("cwd")
(cwd / ALGOKIT_CONFIG).write_text(config_with_override, encoding="utf-8")
(cwd / ".env").touch()

which_mock.add("command_a")
result = invoke(["project", "deploy", "localnet"], cwd=cwd)
result = invoke(["project", "deploy", "customnet"], cwd=cwd)

assert result.exit_code == 1
verify(result.output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ DEBUG: Loading deploy command from project config
DEBUG: Attempting to load project config from {current_working_directory}/.algokit.toml
Using deploy command: /bin/command_a
Loading deployment environment variables...
DEBUG: Using default environment config for algod and indexer for network localnet
Deploying smart contracts from AlgoKit compliant repository 🚀
DEBUG: Running '/bin/command_a' in '{current_working_directory}'
/bin/command_a: picked localnet
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ DEBUG: Loading deploy command from project config
DEBUG: Attempting to load project config from {current_working_directory}/.algokit.toml
Using deploy command: /bin/command_c
Loading deployment environment variables...
DEBUG: Using default environment config for algod and indexer for network testnet
Deploying smart contracts from AlgoKit compliant repository 🚀
DEBUG: Running '/bin/command_c' in '{current_working_directory}'
/bin/command_c: picked testnet
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ DEBUG: Loading deploy command from project config
DEBUG: Attempting to load project config from {current_working_directory}/.algokit.toml
Using deploy command: /bin/command_b
Loading deployment environment variables...
DEBUG: Using default environment config for algod and indexer for network localnet
Deploying smart contracts from AlgoKit compliant repository 🚀
DEBUG: Running '/bin/command_b' in '{current_working_directory}'
/bin/command_b: picked localnet
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ DEBUG: Loading deploy command from project config
DEBUG: Attempting to load project config from {current_working_directory}/.algokit.toml
Using deploy command: /bin/command_a
Loading deployment environment variables...
Error: No such file: {current_working_directory}/.env.localnet
Error: No such file: {current_working_directory}/.env.customnet
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ DEBUG: Loading deploy command from project config
DEBUG: Attempting to load project config from {current_working_directory}/custom_folder/.algokit.toml
Using deploy command: /bin/command_a
Loading deployment environment variables...
DEBUG: Using default environment config for algod and indexer for network testnet
Deploying smart contracts from AlgoKit compliant repository 🚀
DEBUG: Running '/bin/command_a' in '{current_working_directory}/custom_folder'
/bin/command_a: picked base deploy command

1 comment on commit a726756

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/algokit
   __init__.py15753%6–13, 17–24, 32–34
   __main__.py440%1–7
src/algokit/cli
   __init__.py47394%31–34
   codespace.py50982%28, 114, 137, 150–155
   completions.py108992%63–64, 83, 93–99
   dispenser.py121199%77
   doctor.py53394%146–148
   explore.py561573%34–39, 41–46, 80–81, 90
   generate.py70396%76–77, 155
   goal.py47198%79
   init.py3102492%495–496, 501–502, 505, 526, 529–531, 542, 546, 604, 630, 659, 692, 701–703, 706–711, 724, 743, 755–756
   localnet.py1523279%65, 86–113, 133–137, 170, 182, 197–207, 220, 271, 292–293
   task.py34391%25–28
src/algokit/cli/project
   bootstrap.py32197%33
   deploy.py992080%47, 49, 101, 124, 146–148, 227, 234, 248–256, 259–268
   link.py891682%60, 65–66, 101–105, 115–120, 148–149, 218–219, 223
   list.py33585%21–23, 51–56
   run.py46393%38, 71, 160
src/algokit/cli/tasks
   analyze.py81199%81
   assets.py821384%65–66, 72, 74–75, 105, 119, 125–126, 132, 134, 136–137
   ipfs.py51884%52, 80, 92, 94–95, 105–107
   mint.py66494%48, 70, 91, 250
   send_transaction.py651085%52–53, 57, 89, 158, 170–174
   sign_transaction.py59886%21, 28–30, 71–72, 109, 123
   transfer.py39392%26, 90, 117
   utils.py994555%26–34, 40–43, 75–76, 100–101, 125–133, 152–162, 209, 258–259, 279–290, 297–299
   vanity_address.py561082%41, 45–48, 112, 114, 121–123
   wallet.py79495%21, 66, 136, 162
src/algokit/core
   codespace.py1756861%34–37, 41–44, 48–71, 111–112, 125–133, 191, 200–202, 210, 216–217, 229–236, 251–298, 311–313, 338–344, 348, 395
   conf.py57984%12, 24, 28, 36, 38, 73–75, 80
   dispenser.py2022687%91, 123–124, 141–149, 191–192, 198–200, 218–219, 259–260, 318, 332–334, 345–346, 356, 369, 384
   doctor.py65789%67–69, 92–94, 134
   generate.py48394%44, 81, 99
   goal.py65494%21, 36–37, 47
   init.py671085%53, 57–62, 70, 81, 88, 108–109
   log_handlers.py68790%50–51, 63, 112–116, 125
   proc.py45198%99
   sandbox.py2632391%32, 89–92, 97, 101–103, 153, 201–208, 219, 589, 605, 630, 638
   typed_client_generation.py1702088%62–64, 103–108, 132, 135–138, 156, 159–162, 229, 232–235
   utils.py1484073%50–51, 57–69, 125–131, 155, 158, 164–177, 198–200, 229–232, 254
src/algokit/core/compilers
   python.py28582%19–20, 25, 49–50
src/algokit/core/config_commands
   container_engine.py412149%24, 29–31, 47–76
   version_prompt.py921485%37–38, 68, 87–90, 108, 118–125, 148
src/algokit/core/project
   __init__.py53394%50, 86, 145
   bootstrap.py120893%47, 126–127, 149, 176, 207–209
   deploy.py69987%108–111, 120–122, 126, 131
   run.py1251588%83, 88, 97–98, 133–134, 138–139, 143, 147, 261–269, 284
src/algokit/core/tasks
   analyze.py93397%105–112, 187
   ipfs.py63789%58–64, 140, 144, 146, 152
   nfd.py491373%25, 31, 34–41, 70–72, 99–101
   vanity_address.py903462%49–50, 54, 59–75, 92–108, 128–131
   wallet.py71593%37, 129, 155–157
src/algokit/core/tasks/mint
   mint.py781087%123–133, 187
   models.py901188%50, 52, 57, 71–74, 85–88
TOTAL464964186% 

Tests Skipped Failures Errors Time
488 0 💤 0 ❌ 0 🔥 32.600s ⏱️

Please sign in to comment.