Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions bot/kodiak/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from __future__ import annotations

import re
from typing import List, Optional, Sequence, Tuple, TypeVar

import pydantic
import yaml
from pydantic import Field
from typing_extensions import Literal

title_regex = re.compile(r"from (?P<old_version>\S+) to (?P<new_version>\S+)")
Expand Down Expand Up @@ -81,3 +86,43 @@ def dep_version_from_title(x: str) -> Optional[Literal["major", "minor", "patch"
return None
old_version, new_version = res
return _compare_versions(old_version, new_version)


class DependabotUpdate(pydantic.BaseModel):
dependency_name: str = Field(default=..., alias="dependency-name")
dependency_type: str = Field(default=..., alias="dependency-type")
update_type: str = Field(default=..., alias="update-type")

class Config:
allow_population_by_field_name = True


_dependency_regex = re.compile(
r"^-{3}\n(?P<dependencies>(.|\n)*)^\.{3}\n", flags=re.MULTILINE
)


class _ParsedMetadata(pydantic.BaseModel):
updated_dependencies: List[DependabotUpdate] = Field(
default=..., alias="updated-dependencies"
)


def parse_dependabot_metadata(commit_message: str) -> list[DependabotUpdate]:
"""
Parse Dependabot update metadata from commit message.

Dependabot writes structured data about the dependency upgrades as YAML
within the commit message. We can parse this information.
"""
match = _dependency_regex.search(commit_message)
if match is None:
return []
dependencies = match.groupdict().get("dependencies")
if dependencies is None:
return []
metadata_dict = yaml.safe_load(dependencies)
try:
return _ParsedMetadata.parse_obj(metadata_dict).updated_dependencies
except pydantic.ValidationError:
return []
60 changes: 60 additions & 0 deletions bot/kodiak/test_dependencies.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from kodiak.dependencies import (
DependabotUpdate,
_compare_versions,
_extract_versions,
dep_version_from_title,
parse_dependabot_metadata,
)


Expand Down Expand Up @@ -51,3 +53,61 @@ def test_compare_versions() -> None:
_compare_versions(old_version=old_version, new_version=new_version)
== change
)


def test_parse_dependabot_metadata_success() -> None:
EXAMPLE_COMMIT_MESSAGE = """\
Bump rollup from 2.50.1 to 2.50.6
Bumps [rollup](https://github.com/rollup/rollup) from 2.50.1 to 2.50.6.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](rollup/[email protected])

---
updated-dependencies:
- dependency-name: rollup
dependency-type: direct:development
update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
"""
assert parse_dependabot_metadata(EXAMPLE_COMMIT_MESSAGE) == [
DependabotUpdate(
dependency_name="rollup",
dependency_type="direct:development",
update_type="version-update:semver-patch",
)
]


def test_parse_dependabot_metadata_invalid_metadata() -> None:
EXAMPLE_COMMIT_MESSAGE = """\
Bump rollup from 2.50.1 to 2.50.6
Bumps [rollup](https://github.com/rollup/rollup) from 2.50.1 to 2.50.6.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](rollup/[email protected])

---
updated-dependencies:

...

Signed-off-by: dependabot[bot] <[email protected]>
"""
assert parse_dependabot_metadata(EXAMPLE_COMMIT_MESSAGE) == []


def test_parse_dependabot_metadata_missing() -> None:
EXAMPLE_COMMIT_MESSAGE = """\
Bump rollup from 2.50.1 to 2.50.6
Bumps [rollup](https://github.com/rollup/rollup) from 2.50.1 to 2.50.6.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](rollup/[email protected])


Signed-off-by: dependabot[bot] <[email protected]>
"""
assert parse_dependabot_metadata(EXAMPLE_COMMIT_MESSAGE) == []
11 changes: 10 additions & 1 deletion bot/poetry.lock

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

1 change: 1 addition & 0 deletions bot/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ requests = "^2.22"
rure = "^0.2.2"
zstandard = "^0.13.0"
httpx = "^0.18.1"
pyyaml = "^5.4"

[tool.poetry.scripts]
kodiak = 'kodiak.cli:cli'
Expand Down