Skip to content

Commit

Permalink
Merge pull request #76 from uptick/chore/fix-mypy-types
Browse files Browse the repository at this point in the history
chore: add mypy to ci
  • Loading branch information
uptickmetachu authored Sep 4, 2024
2 parents f5965bd + 96ee235 commit 08769ed
Show file tree
Hide file tree
Showing 27 changed files with 163 additions and 184 deletions.
4 changes: 2 additions & 2 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ run = ["uv run py.test"]
run = ["uv run mypy ."]

[tasks."ci"]
depends = ["lint", "format", "test"]
depends = ["lint", "format", "test", "mypy"]

[tasks."helm:lint"]
run = "helm install --dry-run --debug -f charts/gitops/values.yaml debug charts/gitops"

[tasks.release]
description = "Bump release versions across all files"
run = "python release.py"
run = "python release.py"
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.2.0
rev: v0.6.3
hooks:
- id: ruff
args:
- --fix
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.2.0
rev: v0.6.3
hooks:
- id: ruff-format
- repo: https://github.com/commitizen-tools/commitizen
Expand Down
21 changes: 0 additions & 21 deletions Makefile

This file was deleted.

2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ This is a git repository that you set up, where you list out all of your applica

Secrets should be placed in `secrets.env`. The example file `secrets.example.env` has the environment variables you will need to supply.

Gitops has a helm chart defining its deployment. Invoke scripts are provided to make deployment painless. See `tasks.py`.

Add `export GITOPS_APPS_DIRECTORY=~/<cluster-apps-folder>` to invoke gitops from any directory.

Ensure that gitops has `edit` access to the namespace it is deploying to. An example RoleBinding is:
Expand Down
1 change: 0 additions & 1 deletion gitops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
from pathlib import Path

from . import monkeypatches # NOQA
from .utils.cli import success, warning

__version__ = "0.11.0"
Expand Down
2 changes: 1 addition & 1 deletion gitops/common/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def __init__(self, definition: dict | str):
# for backwards compat, any chart definition which is a string, is a git repo
self.type = "git"
self.git_sha = None
self.git_repo_url = definition
self.git_repo_url = definition or None
elif isinstance(definition, dict):
self.type = definition["type"]
self.git_sha = definition.get("git_sha")
Expand Down
2 changes: 1 addition & 1 deletion gitops/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ def git_push(cluster_path: str, retry: int = 3):
attempts = 0
while attempts <= retry:
result = run(f"cd {cluster_path}; git push", warn=True)
if result.exited == 1 and "remote contains work" in result.stderr:
if result and result.exited == 1 and "remote contains work" in result.stderr:
attempts += 1
run(f"cd {cluster_path}; git pull --rebase=true")
else:
Expand Down
2 changes: 1 addition & 1 deletion gitops/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import time

import boto3
import dsnparse
import dsnparse # type: ignore[import]
from invoke import run, task

from .utils import kube
Expand Down
2 changes: 1 addition & 1 deletion gitops/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
namespace.add_task(task)

# Namespace the rarer ones.
namespace.add_collection(db)
namespace.add_collection(db) # type: ignore

program = Program(namespace=namespace, version=version)
8 changes: 0 additions & 8 deletions gitops/monkeypatches.py

This file was deleted.

8 changes: 6 additions & 2 deletions gitops/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ def gen_secret(length: int = 64) -> str:


def get_account_id() -> str:
# TODO REMOVE THIS FUNCTION and account_id in general

if "ACCOUNT_ID" not in CACHE:
# This is not ideal, as it makes an assumption that the account_id of interest is the
# one the user is currently sitting in. Ideally, should ask the cluster (though that is
# messy in its own right, since we don't necessarily want the cluster that's in the
# current context either).
caller_identity = run("aws sts get-caller-identity", hide=True).stdout.strip()
CACHE["ACCOUNT_ID"] = json.loads(caller_identity)["Account"]
result = run("aws sts get-caller-identity", hide=True)
if result:
caller_identity = result.stdout.strip()
CACHE["ACCOUNT_ID"] = json.loads(caller_identity)["Account"]
return CACHE["ACCOUNT_ID"]


Expand Down
4 changes: 2 additions & 2 deletions gitops/utils/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from pathlib import PosixPath
from pathlib import Path

from colorama import Fore
from tabulate import tabulate
Expand All @@ -15,7 +15,7 @@
from .tags import colour_tags, validate_tags


def is_valid_app_directory(directory: PosixPath) -> bool:
def is_valid_app_directory(directory: Path) -> bool:
files = ["deployment.yml", "secrets.yml"]
file_paths = [(directory / file).is_file() for file in files]
return all(file_paths)
Expand Down
1 change: 1 addition & 0 deletions gitops/utils/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections.abc import Callable

from colorama import Fore


Expand Down
2 changes: 1 addition & 1 deletion gitops/utils/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def colour_image(image_tag: str) -> str:
return colourise(bits[0], color_hash(bits[0]))


def color_hash(bit: str) -> Fore: # type: ignore[no-untyped-def]
def color_hash(bit: str) -> str:
return [
Fore.RED,
Fore.GREEN,
Expand Down
16 changes: 8 additions & 8 deletions gitops/utils/kube.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import yaml
from colorama import Fore
from invoke import run
from invoke.exceptions import UnexpectedExit
from invoke.exceptions import Failure, UnexpectedExit

from gitops.common.app import App
from gitops.settings import get_apps_directory
Expand Down Expand Up @@ -55,8 +55,8 @@ async def run_job(
"image": app.image,
"serviceAccountName": app.service_account_name,
}
extra_labels = {}
container_resources = {}
extra_labels: dict[str, str] = {}
container_resources: ContainerResources | None = None

if cpu and memory:
cpu_request = f"{cpu}m" if cpu else ""
Expand Down Expand Up @@ -275,10 +275,10 @@ async def _find_pod() -> str:
_, _, output_log = await async_run(cmd)
logs += output_log

except Exception as e:
except Failure as e:
if "current phase is Succeeded" not in str(e.result.stdout):
raise e
except Exception as e:
except Failure as e:
if "current phase is Succeeded" not in str(e.result.stdout):
raise e
finally:
Expand All @@ -292,9 +292,9 @@ async def wait_for_pod(context: str, namespace: str, pod: str) -> str | None:
while True:
cmd = "kubectl get pod" f" --context {context}" f" -n {namespace}" ' -o jsonpath="{.status.phase}"' f" {pod}"
stdout, _, _ = await async_run(cmd)
stdout = stdout.decode().lower()
if stdout != "pending":
return stdout
output = stdout.decode().lower()
if output != "pending":
return output


def retry(*args: object, max_attempts: int = 3, delay: int = 1): # noqa: C901
Expand Down
8 changes: 4 additions & 4 deletions gitops/utils/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ def increase_indent(self, flow=False, indentless=False):
if pyyaml.safe_dump is pyyaml.dump:
# PyYAML v4.1
SafeDumper = pyyaml.dumper.Dumper
DangerDumper = pyyaml.dumper.DangerDumper
DangerDumper = pyyaml.dumper.DangerDumper # type: ignore
else:
SafeDumper = pyyaml.dumper.SafeDumper
SafeDumper = pyyaml.dumper.SafeDumper # type: ignore
DangerDumper = pyyaml.dumper.Dumper

SafeDumper.increase_indent = increase_indent
SafeDumper.increase_indent = increase_indent # type: ignore
DangerDumper.increase_indent = increase_indent

pyyaml.add_representer(dict, map_representer, Dumper=SafeDumper)
Expand All @@ -43,4 +43,4 @@ def increase_indent(self, flow=False, indentless=False):
# Merge PyYAML namespace into ours.
# This allows users a drop-in replacement:
# import utils.yaml as yaml
from yaml import * # noqa isort:skip
from yaml import * # type: ignore # noqa isort:skip
13 changes: 0 additions & 13 deletions gitops_server/logging_config.py

This file was deleted.

1 change: 0 additions & 1 deletion gitops_server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from gitops_server import settings
from gitops_server.app import app
from gitops_server.logging_config import * # noqa
from gitops_server.workers import DeploymentStatusWorker, DeployQueueWorker

logging.basicConfig(level=logging.INFO)
Expand Down
2 changes: 1 addition & 1 deletion gitops_server/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async def run(command, suppress_errors=False) -> RunOutput:
)

stdout, stderr = await proc.communicate()
exit_code = proc.returncode
exit_code = proc.returncode or 1
if exit_code == 0:
return RunOutput(exit_code=exit_code, output=stdout.decode())
else:
Expand Down
3 changes: 1 addition & 2 deletions gitops_server/utils/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
GITHUB_OAUTH_TOKEN = os.environ.get("GITHUB_OAUTH_TOKEN")


class IssueNotFound(Exception):
...
class IssueNotFound(Exception): ...


class STATUSES:
Expand Down
9 changes: 5 additions & 4 deletions gitops_server/utils/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ async def post(message: str) -> None:
logger.info("POSTING TO SLACK")
data = {"text": message}
async with httpx.AsyncClient() as client:
response = await client.post(SLACK_URL, json=data)
if response.status_code >= 300:
logger.warning("Failed to post a message to slack (see below):")
logger.error(f"{message}", exc_info=True)
if SLACK_URL:
response = await client.post(SLACK_URL, json=data)
if response.status_code >= 300:
logger.warning("Failed to post a message to slack (see below):")
logger.error(f"{message}", exc_info=True)


async def find_commiter_slack_user(name: str, email: str) -> SlackUser | None:
Expand Down
11 changes: 6 additions & 5 deletions gitops_server/workers/deployer/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ async def post_init_summary(source, username, added_apps, updated_apps, removed_

async def post_result(app: App, result: UpdateAppResult, deployer: "Deployer", **kwargs):
if result["exit_code"] != 0:
result = await handle_failed_deploy(app, result, deployer)

deploy_result = await handle_failed_deploy(app, result, deployer)
message = (
result.get("slack_message")
deploy_result["slack_message"]
or f"Failed to deploy app `{result['app_name']}` for cluster `{settings.CLUSTER_NAME}`:\n>>>{result['output']}"
)

Expand Down Expand Up @@ -139,7 +138,8 @@ async def uninstall_app(self, app: App) -> UpdateAppResult:
async with self.semaphore:
logger.info(f"Uninstalling app {app.name!r}.")
result = await run(f"helm uninstall {app.name} -n {app.namespace}", suppress_errors=True)
update_result = UpdateAppResult(app_name=app.name, **result)
if result:
update_result = UpdateAppResult(app_name=app.name, slack_message="", **result)
await post_result(
app=app,
result=update_result,
Expand All @@ -156,6 +156,7 @@ async def update_app_deployment(self, app: App) -> UpdateAppResult | None:
async with self.semaphore:
logger.info(f"Deploying app {app.name!r}.")
if app.chart.type == "git":
assert app.chart.git_repo_url
async with temp_repo(app.chart.git_repo_url, sha=app.chart.git_sha) as chart_folder_path:
await run(f"cd {chart_folder_path}; helm dependency build")
with tempfile.NamedTemporaryFile(suffix=".yml") as cfg:
Expand Down Expand Up @@ -195,7 +196,7 @@ async def update_app_deployment(self, app: App) -> UpdateAppResult | None:
logger.warning("Local is not implemented yet")
return None

update_result = UpdateAppResult(app_name=app.name, **result)
update_result = UpdateAppResult(app_name=app.name, slack_message="", **result)

await post_result(app=app, result=update_result, deployer=self)
return update_result
Expand Down
4 changes: 2 additions & 2 deletions gitops_server/workers/deployer/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from gitops_server import settings
from gitops_server.types import UpdateAppResult
from gitops_server.utils import github
from gitops_server.utils.slack import SlackGroup, find_commiter_slack_user
from gitops_server.utils.slack import SlackGroup, SlackUser, find_commiter_slack_user

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -74,7 +74,7 @@ async def handle_failed_deploy(app: App, result: UpdateAppResult, deployer) -> U
email = deployer.author_email

if "devops" in email.lower() or "tickforge" in email.lower():
slack_user = DEFAULT_USER_GROUP
slack_user: SlackGroup | SlackUser = DEFAULT_USER_GROUP
else:
slack_user = (
await find_commiter_slack_user(name=deployer.author_name, email=deployer.author_email) or DEFAULT_USER_GROUP
Expand Down
6 changes: 3 additions & 3 deletions gitops_server/workers/status_updater/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
import asyncio
import logging

import kubernetes_asyncio
import kubernetes_asyncio.client
import kubernetes_asyncio.config
import kubernetes_asyncio # type:ignore[import-untyped]
import kubernetes_asyncio.client # type:ignore[import-untyped]
import kubernetes_asyncio.config # type:ignore[import-untyped]

from gitops_server.settings import CLUSTER_NAMESPACE
from gitops_server.utils import github
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ build-backend = "hatchling.build"
dev-dependencies = [
"pytest>=8.3.2",
"ruff>=0.6.3",
"types-colorama>=0.4.15.20240311",
"mypy>=1.11.2",
"types-pyyaml>=6.0.12.20240808",
"types-tabulate>=0.9.0.20240106",
"boto3-stubs>=1.35.11",
]


Expand All @@ -50,3 +55,6 @@ style = [
'py://nitpick/resources/any/commitizen',
]
cache = "never"

[tool.mypy]
exclude = ["tests"]
Loading

0 comments on commit 08769ed

Please sign in to comment.