From ef5c086b54ba884a48d06c387380221ec0db6aa6 Mon Sep 17 00:00:00 2001 From: antazoey Date: Mon, 17 Jun 2024 13:04:38 -0500 Subject: [PATCH] docs: document environment variable support in `ape-config.yaml` files (#2148) --- docs/userguides/config.md | 10 ++++++++++ src/ape/utils/misc.py | 2 +- tests/functional/test_config.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/userguides/config.md b/docs/userguides/config.md index b7d58fcc29..0c84ff3f04 100644 --- a/docs/userguides/config.md +++ b/docs/userguides/config.md @@ -19,6 +19,16 @@ However, here is a list of common-use cases requiring the `ape-config.yaml` file 2. Setting up project dependencies: See the [dependencies](#dependencies) section. 3. Declaring your project's plugins: See the [plugins](#plugins) section. +**Environment Variables**: `ape-config.yaml` files support environment-variable expansion. +Simply include environment variables (with the `$` prefix) in your config file and Ape will automatically expand them. + +```yaml +plugin: + secret_rpc: $MY_SECRET_RPC +``` + +This helps keep your secrets out of Ape! + ## Contracts Folder Specify a different path to your `contracts/` directory. diff --git a/src/ape/utils/misc.py b/src/ape/utils/misc.py index 5e36ca3e92..c6c7bed84a 100644 --- a/src/ape/utils/misc.py +++ b/src/ape/utils/misc.py @@ -216,7 +216,7 @@ def load_config(path: Path, expand_envars=True, must_exist=False) -> dict: and is able to be load. Returns: - Dict (dict): Configured settings parsed from a config file. + dict: Configured settings parsed from a config file. """ if path.is_file(): contents = path.read_text() diff --git a/tests/functional/test_config.py b/tests/functional/test_config.py index a9effbaf93..2e52d95c33 100644 --- a/tests/functional/test_config.py +++ b/tests/functional/test_config.py @@ -1,3 +1,4 @@ +import os from pathlib import Path from typing import Optional, Union @@ -39,6 +40,33 @@ def test_model_validate_path_contracts_folder(): assert cfg.contracts_folder == str(path) +def test_validate_file(): + value = "pathtowherever" + with create_tempdir() as temp_dir: + file = temp_dir / "ape-config.yaml" + file.write_text(f"contracts_folder: {value}") + actual = ApeConfig.validate_file(file) + + assert actual.contracts_folder == value + + +def test_validate_file_expands_env_vars(): + secret = "mycontractssecretfolder" + env_var_name = "APE_TEST_CONFIG_SECRET_CONTRACTS_FOLDER" + os.environ[env_var_name] = secret + + try: + with create_tempdir() as temp_dir: + file = temp_dir / "ape-config.yaml" + file.write_text(f"contracts_folder: ${env_var_name}") + + actual = ApeConfig.validate_file(file) + assert actual.contracts_folder == secret + finally: + if env_var_name in os.environ: + del os.environ[env_var_name] + + def test_deployments(networks_connected_to_tester, owner, vyper_contract_container, project): _ = networks_connected_to_tester # Connection needs to lookup config.