diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..03155a52 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,20 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + groups: + production-dependencies: + dependency-type: "production" + development-dependencies: + dependency-type: "development" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/dependabot-prs.yml b/.github/workflows/dependabot-prs.yml new file mode 100644 index 00000000..8c7745ee --- /dev/null +++ b/.github/workflows/dependabot-prs.yml @@ -0,0 +1,26 @@ +name: Dependabot Pull Request Metadata +on: pull_request_target + +jobs: + build: + permissions: + pull-requests: read + + runs-on: ubuntu-latest + if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }} + + steps: + - name: Fetch Dependabot metadata + id: dependabot-metadata + uses: dependabot/fetch-metadata@v2 + with: + alert-lookup: true + compat-lookup: true + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Add a label for all PRs with an alert state + if: ${{ steps.dependabot-metadata.outputs.alert-state != '' }} + run: gh pr edit "$PR_URL" --add-label "vulnerability" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml new file mode 100644 index 00000000..193e5bb4 --- /dev/null +++ b/.github/workflows/snyk.yml @@ -0,0 +1,28 @@ +name: Snyk + +on: + workflow_dispatch: + + schedule: + - cron: "0 9 * * 1" # runs each Monday at 9:00 UTC + +permissions: + contents: read + security-events: write + +jobs: + security: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/python-3.8@master + continue-on-error: true # To make sure that SARIF upload gets called + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=medium --file=requirements.txt --sarif-file-output=snyk.sarif + - name: Upload result to GitHub Code Scanning + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: snyk.sarif diff --git a/CHANGELOG.md b/CHANGELOG.md index dca289f7..1890728f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,17 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a Ch ### Fixes + +## v4.0.1 (2024-06-10) + +### New + +### Changes + +### Fixes +- correcting how SeedFarmer stores deployed manifests of previously deployed modules in SSM + + ## v4.0.0 (2024-06-03) ### New diff --git a/VERSION b/VERSION index 72490fd8..ee74734a 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1 @@ -4.0.0 - +4.1.0 diff --git a/docs/requirements-docs.in b/docs/requirements-docs.in index 5de9c165..2e2ff538 100644 --- a/docs/requirements-docs.in +++ b/docs/requirements-docs.in @@ -1,5 +1,5 @@ sphinx-autoapi==2.1.0 -sphinx-rtd-theme==1.2.1 +sphinx-rtd-theme==1.3.0 sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 @@ -7,11 +7,11 @@ sphinxcontrib-jquery==4.1 sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 -sphinx-click==5.1.0 +sphinx-click==6.0.0 myst_parser==1.0.0 docutils~=0.16 -PyYAML==5.4 +PyYAML==6.0.1 urllib3~=1.26.18 -wheel==0.38.1 -typing-extensions==4.5.0 -certifi~=2023.7.22 +wheel==0.43.0 +typing-extensions==4.12.2 +certifi~=2024.6.2 diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 6af16f70..d6456361 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -10,7 +10,7 @@ astroid==2.15.5 # via sphinx-autoapi babel==2.12.1 # via sphinx -certifi==2023.7.22 +certifi==2024.6.2 # via # -r docs/requirements-docs.in # requests @@ -29,6 +29,8 @@ idna==3.7 # via requests imagesize==1.4.1 # via sphinx +importlib-metadata==7.1.0 + # via sphinx jinja2==3.1.4 # via # myst-parser @@ -52,16 +54,18 @@ packaging==23.1 # via sphinx pygments==2.15.1 # via sphinx -pyyaml==5.4 +pytz==2024.1 + # via babel +pyyaml==6.0.1 # via # -r docs/requirements-docs.in # myst-parser # sphinx-autoapi -requests==2.32.0 +requests==2.32.3 # via sphinx snowballstemmer==2.2.0 # via sphinx -sphinx==6.2.1 +sphinx==5.3.0 # via # myst-parser # sphinx-autoapi @@ -70,9 +74,9 @@ sphinx==6.2.1 # sphinxcontrib-jquery sphinx-autoapi==2.1.0 # via -r docs/requirements-docs.in -sphinx-click==5.1.0 +sphinx-click==6.0.0 # via -r docs/requirements-docs.in -sphinx-rtd-theme==1.2.1 +sphinx-rtd-theme==1.3.0 # via -r docs/requirements-docs.in sphinxcontrib-applehelp==1.0.4 # via @@ -102,15 +106,19 @@ sphinxcontrib-serializinghtml==1.1.5 # via # -r docs/requirements-docs.in # sphinx -typing-extensions==4.5.0 - # via -r docs/requirements-docs.in +typing-extensions==4.12.2 + # via + # -r docs/requirements-docs.in + # astroid unidecode==1.3.6 # via sphinx-autoapi urllib3==1.26.18 # via # -r docs/requirements-docs.in # requests -wheel==0.38.1 +wheel==0.43.0 # via -r docs/requirements-docs.in wrapt==1.15.0 # via astroid +zipp==3.19.2 + # via importlib-metadata diff --git a/requirements-dev.in b/requirements-dev.in index 9c62df01..0b577552 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -1,24 +1,24 @@ awscli~=1.31.13 -certifi~=2023.7.22 +certifi~=2024.6.2 check-manifest~=0.48 -mypy~=0.961 +mypy~=1.10 myst-parser~=0.18.0 -pip-tools~=6.14.0 -pydot~=1.4.2 +pip-tools~=7.4.1 +pydot~=2.0.0 pyroma~=4.0 -pytest~=7.2.0 -pytest-cov~=4.0.0 -pytest-mock~=3.10.0 +pytest~=8.2.2 +pytest-cov~=5.0.0 +pytest-mock~=3.14.0 pytest-ordering~=0.6 -ruff~=0.4.4 -twine~=4.0.1 -types-PyYAML~=6.0.8 -types-setuptools~=57.4.17 -wheel~=0.38.1 +ruff~=0.4.8 +twine~=5.1.0 +types-PyYAML~=6.0.12 +types-setuptools~=70.0.0 +wheel~=0.43.0 sphinx-autoapi~=1.8.0 -sphinx-rtd-theme~=1.0.0 -sphinx~=4.3.0 -moto[s3,sts,iam,codebuild,secretsmanager,ssm]~=4.0.9 -requests~=2.32.0 +sphinx-rtd-theme~=1.3.0 +sphinx~=5.3.0 +moto[s3,sts,iam,codebuild,secretsmanager,ssm]~=5.0.9 +requests~=2.32.3 werkzeug~=3.0.3 urllib3~=1.26.18 \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index c51189c5..6e26e1d9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.12 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # pip-compile --output-file=requirements-dev.txt requirements-dev.in @@ -8,8 +8,6 @@ alabaster==0.7.13 # via sphinx astroid==2.15.8 # via sphinx-autoapi -attrs==23.2.0 - # via pytest awscli==1.31.13 # via -r requirements-dev.in babel==2.14.0 @@ -24,12 +22,12 @@ botocore==1.33.13 # boto3 # moto # s3transfer -build==0.10.0 +build==1.2.1 # via # check-manifest # pip-tools # pyroma -certifi==2023.7.22 +certifi==2024.6.2 # via # -r requirements-dev.in # requests @@ -57,12 +55,18 @@ docutils==0.16 # readme-renderer # sphinx # sphinx-rtd-theme +exceptiongroup==1.2.1 + # via pytest idna==3.7 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==4.2.0 - # via twine +importlib-metadata==7.1.0 + # via + # build + # keyring + # sphinx + # twine iniconfig==2.0.0 # via pytest jaraco-classes==3.2.3 @@ -93,7 +97,6 @@ markdown-it-py==2.2.0 markupsafe==2.1.5 # via # jinja2 - # moto # werkzeug mdit-py-plugins==0.3.5 # via myst-parser @@ -101,9 +104,9 @@ mdurl==0.1.2 # via markdown-it-py more-itertools==9.1.0 # via jaraco-classes -moto[codebuild,iam,s3,secretsmanager,ssm,sts]==4.0.13 +moto[codebuild,iam,s3,secretsmanager,ssm,sts]==5.0.9 # via -r requirements-dev.in -mypy==0.991 +mypy==1.10.0 # via -r requirements-dev.in mypy-extensions==1.0.0 # via mypy @@ -115,17 +118,19 @@ packaging==23.2 # pyroma # pytest # sphinx -pip-tools==6.14.0 +pip-tools==7.4.1 # via -r requirements-dev.in pkginfo==1.9.6 # via twine -pluggy==1.2.0 +pluggy==1.5.0 # via pytest +py-partiql-parser==0.5.5 + # via moto pyasn1==0.5.1 # via rsa pycparser==2.21 # via cffi -pydot==1.4.2 +pydot==2.0.0 # via -r requirements-dev.in pygments==2.17.2 # via @@ -136,18 +141,20 @@ pygments==2.17.2 pyparsing==3.1.1 # via pydot pyproject-hooks==1.0.0 - # via build + # via + # build + # pip-tools pyroma==4.2 # via -r requirements-dev.in -pytest==7.2.2 +pytest==8.2.2 # via # -r requirements-dev.in # pytest-cov # pytest-mock # pytest-ordering -pytest-cov==4.0.0 +pytest-cov==5.0.0 # via -r requirements-dev.in -pytest-mock==3.10.0 +pytest-mock==3.14.0 # via -r requirements-dev.in pytest-ordering==0.6 # via -r requirements-dev.in @@ -155,6 +162,8 @@ python-dateutil==2.8.2 # via # botocore # moto +pytz==2024.1 + # via babel pyyaml==6.0.1 # via # awscli @@ -164,7 +173,7 @@ pyyaml==6.0.1 # sphinx-autoapi readme-renderer==37.3 # via twine -requests==2.32.0 +requests==2.32.3 # via # -r requirements-dev.in # moto @@ -183,7 +192,7 @@ rich==13.7.0 # via twine rsa==4.7.2 # via awscli -ruff==0.4.4 +ruff==0.4.8 # via -r requirements-dev.in s3transfer==0.8.2 # via @@ -197,15 +206,16 @@ six==1.16.0 # python-dateutil snowballstemmer==2.2.0 # via sphinx -sphinx==4.3.2 +sphinx==5.3.0 # via # -r requirements-dev.in # myst-parser # sphinx-autoapi # sphinx-rtd-theme + # sphinxcontrib-jquery sphinx-autoapi==1.8.4 # via -r requirements-dev.in -sphinx-rtd-theme==1.0.0 +sphinx-rtd-theme==1.3.0 # via -r requirements-dev.in sphinxcontrib-applehelp==1.0.2 # via sphinx @@ -213,26 +223,39 @@ sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.0 # via sphinx +sphinxcontrib-jquery==4.1 + # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx +tomli==2.0.1 + # via + # build + # check-manifest + # coverage + # mypy + # pip-tools + # pyproject-hooks + # pytest trove-classifiers==2024.2.22 # via pyroma -twine==4.0.2 +twine==5.1.0 # via -r requirements-dev.in -types-pyyaml==6.0.12.12 +types-pyyaml==6.0.12.20240311 # via # -r requirements-dev.in # responses -types-setuptools==57.4.18 +types-setuptools==70.0.0.20240524 # via -r requirements-dev.in -typing-extensions==4.7.1 +typing-extensions==4.12.2 # via + # astroid # mypy # myst-parser + # rich unidecode==1.3.8 # via sphinx-autoapi urllib3==1.26.18 @@ -248,7 +271,7 @@ werkzeug==3.0.3 # via # -r requirements-dev.in # moto -wheel==0.38.4 +wheel==0.43.0 # via # -r requirements-dev.in # pip-tools diff --git a/requirements.txt b/requirements.txt index 6803da1a..575dd9b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,21 +4,21 @@ # # pip-compile # -annotated-types==0.5.0 +annotated-types==0.7.0 # via pydantic -arrow==1.2.3 +arrow==1.3.0 # via jinja2-time aws-codeseeder==1.0.0 # via seed-farmer (setup.py) binaryornot==0.4.4 # via cookiecutter -boto3==1.33.13 +boto3==1.34.122 # via aws-codeseeder -botocore==1.33.13 +botocore==1.34.122 # via # boto3 # s3transfer -certifi==2023.7.22 +certifi==2024.6.2 # via # aws-codeseeder # requests @@ -38,7 +38,7 @@ coloredlogs==15.0.1 # via executor commonmark==0.9.1 # via rich -cookiecutter==2.1.1 +cookiecutter==2.6.0 # via seed-farmer (setup.py) executor==23.2 # via seed-farmer (setup.py) @@ -48,7 +48,7 @@ gitdb==4.0.11 # via gitpython gitignore-parser==0.1.11 # via seed-farmer (setup.py) -gitpython==3.1.42 +gitpython==3.1.43 # via seed-farmer (setup.py) humanfriendly==10.0 # via @@ -71,23 +71,23 @@ markupsafe==2.1.5 # via jinja2 mypy-extensions==1.0.0 # via aws-codeseeder -packaging==23.2 +packaging==24.1 # via seed-farmer (setup.py) property-manager==3.0 # via executor -pydantic==2.5.3 +pydantic==2.7.3 # via seed-farmer (setup.py) -pydantic-core==2.14.6 +pydantic-core==2.18.4 # via pydantic -pygments==2.17.2 +pygments==2.18.0 # via rich -pyhumps==3.5.3 +pyhumps==3.8.0 # via seed-farmer (setup.py) -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via # arrow # botocore -python-dotenv==0.21.1 +python-dotenv==1.0.1 # via seed-farmer (setup.py) python-slugify==8.0.4 # via cookiecutter @@ -97,13 +97,13 @@ pyyaml==6.0.1 # cfn-flip # cookiecutter # seed-farmer (setup.py) -requests==2.32.0 +requests==2.32.3 # via # cookiecutter # seed-farmer (setup.py) -rich==12.4.4 +rich==13.7.1 # via seed-farmer (setup.py) -s3transfer==0.8.2 +s3transfer==0.10.1 # via boto3 six==1.16.0 # via @@ -114,7 +114,7 @@ smmap==5.0.1 # via gitdb text-unidecode==1.3 # via python-slugify -typing-extensions==4.11.0 +typing-extensions==4.12.2 # via # pydantic # pydantic-core diff --git a/seedfarmer/checksum.py b/seedfarmer/checksum.py index c8db589f..194431ac 100644 --- a/seedfarmer/checksum.py +++ b/seedfarmer/checksum.py @@ -16,7 +16,7 @@ import hashlib import os from pathlib import Path -from typing import Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional from gitignore_parser import parse_gitignore @@ -120,9 +120,7 @@ def scandir(dirname: str) -> List[str]: files = [ f.path for f in os.scandir(dirname) - if f.is_file() - and os.path.split(f)[1] not in cast(List[str], excluded_files) - and not _evaluate_file(f.path, ignore_maps) + if f.is_file() and os.path.split(f)[1] not in excluded_files and not _evaluate_file(f.path, ignore_maps) ] all_files.extend(files) subfolders = [f.path for f in os.scandir(dirname) if f.is_dir()] diff --git a/seedfarmer/commands/_deployment_commands.py b/seedfarmer/commands/_deployment_commands.py index b06d6374..09ee0ba8 100644 --- a/seedfarmer/commands/_deployment_commands.py +++ b/seedfarmer/commands/_deployment_commands.py @@ -192,6 +192,7 @@ def _execute_destroy(mdo: ModuleDeployObject) -> Optional[ModuleDeploymentRespon def _deploy_validated_deployment( deployment_manifest: DeploymentManifest, + deployment_manifest_wip: DeploymentManifest, groups_to_deploy: List[ModulesManifest], dryrun: bool, ) -> None: @@ -206,17 +207,17 @@ def _deploy_validated_deployment( f"Modules scheduled to be deployed (created or updated): {deployment_manifest.name}", mods_would_deploy ) return - deployment_manifest.groups = groups_to_deploy + deployment_manifest_wip.groups = groups_to_deploy print_manifest_inventory( - f"Modules scheduled to be deployed (created or updated): {deployment_manifest.name}", - deployment_manifest, + f"Modules scheduled to be deployed (created or updated): {deployment_manifest_wip.name}", + deployment_manifest_wip, True, ) if _logger.isEnabledFor(logging.DEBUG): _logger.debug( - "DeploymentManifest for deploy after filter = %s", json.dumps(deployment_manifest.model_dump()) + "DeploymentManifest for deploy after filter = %s", json.dumps(deployment_manifest_wip.model_dump()) ) - for _group in deployment_manifest.groups: + for _group in deployment_manifest_wip.groups: if len(_group.modules) > 0: threads = _group.concurrency if _group.concurrency else len(_group.modules) with concurrent.futures.ThreadPoolExecutor(max_workers=threads, thread_name_prefix="Deploy") as workers: @@ -231,7 +232,7 @@ def _exec_deploy(mdo: ModuleDeployObject) -> ModuleDeploymentResponse: for _module in _group.modules: if _module and _module.deploy_spec: mdo = ModuleDeployObject( - deployment_manifest=deployment_manifest, + deployment_manifest=deployment_manifest_wip, group_name=_group.name, module_name=_module.name, ) @@ -255,7 +256,7 @@ def _exec_deploy(mdo: ModuleDeployObject) -> ModuleDeploymentResponse: error_message="At least one module failed to deploy...exiting deployment" ) - print_manifest_inventory(f"Modules Deployed: {deployment_manifest.name}", deployment_manifest, False) + print_manifest_inventory(f"Modules Deployed: {deployment_manifest_wip.name}", deployment_manifest_wip, False) else: _logger.info(" All modules in %s up to date", deployment_manifest.name) # Write the deployment manifest once completed to preserve group order @@ -468,10 +469,13 @@ def deploy_deployment( By default False """ - deployment_name = cast(str, deployment_manifest.name) + deployment_manifest_wip = deployment_manifest.model_copy() + deployment_name = cast(str, deployment_manifest_wip.name) _logger.debug("Setting up deployment for %s", deployment_name) - print_manifest_inventory(f"Modules added to manifest: {deployment_manifest.name}", deployment_manifest, True) + print_manifest_inventory( + f"Modules added to manifest: {deployment_manifest_wip.name}", deployment_manifest_wip, True + ) if deployment_manifest.force_dependency_redeploy: _logger.warn("You have configured your deployment to FORCE all dependent modules to redeploy") @@ -480,7 +484,7 @@ def deploy_deployment( groups_to_deploy = [] unchanged_modules = [] _group_mod_to_deploy: List[str] = [] - for group in deployment_manifest.groups: + for group in deployment_manifest_wip.groups: modules_to_deploy = [] _logger.info(" Verifying all modules in %s for deploy ", group.name) du.validate_group_parameters(group=group) @@ -516,7 +520,9 @@ def deploy_deployment( data_files=module.data_files, excluded_files=md5_excluded_module_files, ) - resolve_params_for_checksum(deployment_manifest=deployment_manifest, module=module, group_name=group.name) + resolve_params_for_checksum( + deployment_manifest=deployment_manifest_wip, module=module, group_name=group.name + ) module.manifest_md5 = hashlib.md5( json.dumps(module.model_dump(), sort_keys=True).encode("utf-8") @@ -560,6 +566,7 @@ def deploy_deployment( ) _deploy_validated_deployment( deployment_manifest=deployment_manifest, + deployment_manifest_wip=deployment_manifest_wip, groups_to_deploy=groups_to_deploy, dryrun=dryrun, ) diff --git a/seedfarmer/commands/_project_policy_commands.py b/seedfarmer/commands/_project_policy_commands.py index 4f74fb8e..e708eb7a 100644 --- a/seedfarmer/commands/_project_policy_commands.py +++ b/seedfarmer/commands/_project_policy_commands.py @@ -21,4 +21,4 @@ def get_default_project_policy() -> None: with open(os.path.join(CLI_ROOT, DEFAULT_PROJECT_POLICY_PATH), "rb") as f: - shutil.copyfileobj(f, sys.stdout.buffer) + shutil.copyfileobj(f, sys.stdout.buffer) # type: ignore[misc] diff --git a/seedfarmer/mgmt/deploy_utils.py b/seedfarmer/mgmt/deploy_utils.py index 11e2a055..38588b66 100644 --- a/seedfarmer/mgmt/deploy_utils.py +++ b/seedfarmer/mgmt/deploy_utils.py @@ -655,7 +655,7 @@ def _populate_groups_to_remove( skip_deploy_spec=False, ), } - destroy_group_list.append(ModulesManifest(**group_manifest)) + destroy_group_list.append(ModulesManifest(**group_manifest)) # type: ignore[arg-type] return destroy_group_list diff --git a/seedfarmer/mgmt/git_support.py b/seedfarmer/mgmt/git_support.py index e23755ac..3c68e32c 100644 --- a/seedfarmer/mgmt/git_support.py +++ b/seedfarmer/mgmt/git_support.py @@ -54,7 +54,7 @@ def clone_module_repo(git_path: str) -> Tuple[str, str, Optional[str]]: if "?" in git_path: git_path, query = git_path.split("?") query_params = parse_qs(query) - ref = query_params.get("ref", [None])[0] # type: ignore + ref = query_params.get("ref", [None])[0] if "depth" in query_params and query_params["depth"][0].isnumeric(): depth = int(query_params["depth"][0]) diff --git a/seedfarmer/mgmt/module_info.py b/seedfarmer/mgmt/module_info.py index b6bd5681..c51bb73d 100644 --- a/seedfarmer/mgmt/module_info.py +++ b/seedfarmer/mgmt/module_info.py @@ -792,7 +792,7 @@ def _fetch_helper( name: str, params_cache: Optional[Dict[str, Any]] = None, session: Optional[Session] = None ) -> Optional[Dict[str, Any]]: if params_cache: - return params_cache.get(name, None) + return params_cache.get(name, None) # type: ignore[no-any-return] else: return ssm.get_parameter_if_exists(name=name, session=session) diff --git a/seedfarmer/models/manifests/_deployment_manifest.py b/seedfarmer/models/manifests/_deployment_manifest.py index e4e2c558..e04d97f5 100644 --- a/seedfarmer/models/manifests/_deployment_manifest.py +++ b/seedfarmer/models/manifests/_deployment_manifest.py @@ -130,7 +130,7 @@ class NameGenerator(CamelModel): prefix: Union[str, ValueFromRef] suffix: Union[str, ValueFromRef] - def _get_value(self, value: Union[str, ValueFromRef]) -> str: + def _get_value(self, value: Union[str, ValueFromRef]) -> str: # type: ignore[override] if isinstance(value, str): return value elif isinstance(value, ValueFromRef): diff --git a/seedfarmer/utils.py b/seedfarmer/utils.py index 12530879..836f4475 100644 --- a/seedfarmer/utils.py +++ b/seedfarmer/utils.py @@ -61,10 +61,10 @@ def upper_snake_case(value: str) -> str: str the string standardized """ - if humps.is_camelcase(value): # type: ignore - return humps.decamelize(value).upper() # type: ignore - elif humps.is_pascalcase(value): # type: ignore - return humps.depascalize(value).upper() # type: ignore + if humps.is_camelcase(value): + return humps.decamelize(value).upper() + elif humps.is_pascalcase(value): + return humps.depascalize(value).upper() else: return value.replace("-", "_").upper() diff --git a/setup.py b/setup.py index c6f6ead3..38e1ca59 100644 --- a/setup.py +++ b/setup.py @@ -46,20 +46,20 @@ python_requires=">=3.8,<3.13", install_requires=[ "aws-codeseeder~=1.0.0", - "cookiecutter~=2.1.0", - "pyhumps~=3.5.0", - "pydantic~=2.5.3", + "cookiecutter>=2.1,<2.7", + "pyhumps>=3.5,<3.9", + "pydantic>=2.5.3,<2.8.0", "executor~=23.2", "typing-extensions>=4.6.3", - "rich~=12.4.0", + "rich>=12.4,<13.8", "requests>=2.28,<2.33", - "python-dotenv~=0.21.0", + "python-dotenv>=0.21,<1.1", "gitpython~=3.1.30", "gitignore-parser~=0.1.2", "pyyaml~=6.0.1", "urllib3~=1.26.17", - "certifi~=2023.7.22", - "packaging~=23.2", + "certifi>=2023.7.22,<2024.7.0", + "packaging>=23.2,<25.0", ], entry_points={"console_scripts": ["seedfarmer = seedfarmer.__main__:main"]}, classifiers=[ diff --git a/test/unit-test/test_cli_arg.py b/test/unit-test/test_cli_arg.py index b49c5033..b1ee781c 100644 --- a/test/unit-test/test_cli_arg.py +++ b/test/unit-test/test_cli_arg.py @@ -18,7 +18,7 @@ import mock_data.mock_manifests as mock_manifests import pytest from _test_cli_helper_functions import _test_command -from moto import mock_sts +from moto import mock_aws from seedfarmer import config from seedfarmer.__main__ import apply, bootstrap, destroy, init, metadata, projectpolicy, remove, store, version @@ -75,7 +75,7 @@ def env_file2(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_bootstrap.py b/test/unit-test/test_commands_bootstrap.py index af3b5ea8..5c45cc8c 100644 --- a/test/unit-test/test_commands_bootstrap.py +++ b/test/unit-test/test_commands_bootstrap.py @@ -2,7 +2,7 @@ import boto3 import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer import seedfarmer.commands._bootstrap_commands as bc @@ -24,7 +24,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_deployment.py b/test/unit-test/test_commands_deployment.py index 682e15e6..49c03c0d 100644 --- a/test/unit-test/test_commands_deployment.py +++ b/test/unit-test/test_commands_deployment.py @@ -7,7 +7,7 @@ import mock_data.mock_manifests as mock_manifests import mock_data.mock_module_info_huge as mock_module_info_huge import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.commands._deployment_commands as dc import seedfarmer.errors @@ -34,7 +34,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_module.py b/test/unit-test/test_commands_module.py index fc399a2a..b391a07c 100644 --- a/test/unit-test/test_commands_module.py +++ b/test/unit-test/test_commands_module.py @@ -3,7 +3,7 @@ import pytest import yaml -from moto import mock_sts +from moto import mock_aws import seedfarmer.commands._module_commands as mc import seedfarmer.errors @@ -27,7 +27,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_network_parameters.py b/test/unit-test/test_commands_network_parameters.py index 868d6c5d..0521df20 100644 --- a/test/unit-test/test_commands_network_parameters.py +++ b/test/unit-test/test_commands_network_parameters.py @@ -2,7 +2,7 @@ from typing import Any, Dict, cast import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.commands._network_parameter_commands as npc import seedfarmer.errors @@ -24,7 +24,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_parameters.py b/test/unit-test/test_commands_parameters.py index ec0cbbd1..cfbd2313 100644 --- a/test/unit-test/test_commands_parameters.py +++ b/test/unit-test/test_commands_parameters.py @@ -2,7 +2,7 @@ import pydantic_core import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.commands._parameter_commands as pc import seedfarmer.errors @@ -24,7 +24,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_commands_stack.py b/test/unit-test/test_commands_stack.py index 4047e91c..87758173 100644 --- a/test/unit-test/test_commands_stack.py +++ b/test/unit-test/test_commands_stack.py @@ -2,7 +2,7 @@ import pytest import yaml -from moto import mock_sts +from moto import mock_aws import seedfarmer.commands._stack_commands as sc from seedfarmer.models.manifests import DeploymentManifest @@ -23,7 +23,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_mgmt_build_info.py b/test/unit-test/test_mgmt_build_info.py index 70e8fa90..a98beb9a 100644 --- a/test/unit-test/test_mgmt_build_info.py +++ b/test/unit-test/test_mgmt_build_info.py @@ -17,7 +17,7 @@ import mock_data.mock_build_info as mock_build_info import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.mgmt.build_info as bi from seedfarmer.services._service_utils import boto3_client @@ -39,7 +39,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_mgmt_deploy_utils.py b/test/unit-test/test_mgmt_deploy_utils.py index b6bd2308..eb946d12 100644 --- a/test/unit-test/test_mgmt_deploy_utils.py +++ b/test/unit-test/test_mgmt_deploy_utils.py @@ -21,7 +21,7 @@ import mock_data.mock_manifests as mock_manifests import mock_data.mock_module_info_huge as mock_module_info_huge import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.errors import seedfarmer.mgmt.deploy_utils as du @@ -45,7 +45,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_mgmt_git_support.py b/test/unit-test/test_mgmt_git_support.py index eabed574..03fff9c9 100644 --- a/test/unit-test/test_mgmt_git_support.py +++ b/test/unit-test/test_mgmt_git_support.py @@ -16,7 +16,7 @@ import os import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.mgmt.git_support as sf_git from seedfarmer.services._service_utils import boto3_client @@ -38,7 +38,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) diff --git a/test/unit-test/test_services.py b/test/unit-test/test_services.py index d765b140..36a61da2 100644 --- a/test/unit-test/test_services.py +++ b/test/unit-test/test_services.py @@ -13,7 +13,7 @@ import boto3 import pytest -from moto import mock_codebuild, mock_iam, mock_ssm, mock_sts +from moto import mock_aws from seedfarmer.services import _service_utils from seedfarmer.services._service_utils import boto3_client @@ -40,7 +40,7 @@ def session(aws_credentials): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None) @@ -57,7 +57,7 @@ def session_manager(sts_client): @pytest.fixture(scope="function") def secretsmanager_client(aws_credentials, session_manager): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="secretsmanager", session=None) @@ -86,7 +86,7 @@ def test_utils_get_account_id(sts_client, mocker): @pytest.fixture(scope="function") def iam_client(aws_credentials): - with mock_iam(): + with mock_aws(): yield _service_utils.boto3_client(service_name="iam", session=None) @@ -95,7 +95,7 @@ def iam_client(aws_credentials): def test_codebuild(session) -> None: import seedfarmer.services._codebuild as codebuild - with mock_codebuild(): + with mock_aws(): codebuild.get_build_data(build_ids=["codebuild:12345"], session=session) codebuild.get_build_data(build_ids=["12345"], session=session) @@ -105,7 +105,7 @@ def test_codebuild(session) -> None: def test_iam(iam_client, session) -> None: import seedfarmer.services._iam as iam - with mock_iam(): + with mock_aws(config={"iam": {"load_aws_managed_policies": True}}): iam.create_check_iam_role( project_name="test", deployment_name="test", @@ -160,7 +160,7 @@ def test_iam(iam_client, session) -> None: def test_get_ssm_params(session) -> None: import seedfarmer.services._ssm as ssm - with mock_ssm(): + with mock_aws(): ssm.put_parameter(name="/myapp/test/", obj={"Hey": "tsting"}, session=session) ssm.does_parameter_exist(name="/myapp/test/", session=session) ssm.does_parameter_exist(name="/garbage/", session=session) @@ -174,7 +174,7 @@ def test_get_ssm_params(session) -> None: def test_put_ssm_param(session) -> None: import seedfarmer.services._ssm as ssm - with mock_ssm(): + with mock_aws(): ssm.put_parameter(name="/myapp/test/", obj={"Hey": "tsting"}, session=session) @@ -182,7 +182,7 @@ def test_put_ssm_param(session) -> None: def test_list_ssm_param(session) -> None: import seedfarmer.services._ssm as ssm - with mock_ssm(): + with mock_aws(): ssm.put_parameter(name="/myapp/test/", obj={"Hey": "testing"}, session=session) ssm.list_parameters(prefix="/myapp/test/", session=session) ssm.list_parameters_with_filter(prefix="/myapp/", contains_string="test", session=session) @@ -192,7 +192,7 @@ def test_list_ssm_param(session) -> None: def test_delete_ssm_param(session) -> None: import seedfarmer.services._ssm as ssm - with mock_ssm(): + with mock_aws(): ssm.delete_parameters(parameters=["/myapp", "/myapp/test/"], session=session) ssm.delete_parameters( parameters=[ @@ -215,7 +215,7 @@ def test_delete_ssm_param(session) -> None: def test_get_ssm_metadata(session) -> None: import seedfarmer.services._ssm as ssm - with mock_ssm(): + with mock_aws(): ssm.put_parameter(name="/myapp/test/", obj={"Hey": "testing"}, session=session) ssm.describe_parameter(name="/myapp/test/", session=session) diff --git a/test/unit-test/test_session_manager.py b/test/unit-test/test_session_manager.py index 941c82ad..c1000ab4 100644 --- a/test/unit-test/test_session_manager.py +++ b/test/unit-test/test_session_manager.py @@ -15,7 +15,7 @@ import os import pytest -from moto import mock_sts +from moto import mock_aws import seedfarmer.errors from seedfarmer.services._service_utils import boto3_client @@ -40,7 +40,7 @@ def aws_credentials(): @pytest.fixture(scope="function") def sts_client(aws_credentials): - with mock_sts(): + with mock_aws(): yield boto3_client(service_name="sts", session=None)