Skip to content
Merged
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
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,11 @@ dmypy.json
cython_debug/

# App
config.yaml
/config.yaml
docker-compose.yaml
github-webhook-server.json
config-dev.yaml
/config-dev.yaml
local-run.sh
.scannerwork/
webhook-server.private-key.pem
log-colors.json
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ repos:
rev: v1.11.2
hooks:
- id: mypy
exclude: (tests/*)
Comment thread
myakove marked this conversation as resolved.
additional_dependencies: [types-requests, types-PyYAML]
2 changes: 1 addition & 1 deletion example.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ auto-verified-and-merged-users:
jira:
server: <JIRA URL>
project: <PROJECT KEY>
tokan: <JIRA TOKEN>
token: <JIRA TOKEN>
user-mapping:
<GITHUB USER>: <JIRA USER> # if github user is not the same as jira

Expand Down
67 changes: 66 additions & 1 deletion poetry.lock

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

5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ string-color = "^1.2.3"
ipdb = "^0.13.13"
ipython = "*"


[tool.poetry.group.tests.dependencies]
pytest-mock = "^3.14.0"
pytest = "^8.3.3"

[tool.poetry-dynamic-versioning]
enable = true
pattern = "((?P<epoch>\\d+)!)?(?P<base>\\d+(\\.\\d+)*)"
Expand Down
10 changes: 9 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
[tox]
envlist = unused-code, pytest
skipsdist = True

[testenv]
[testenv:unused-code]
deps =
python-utility-scripts
commands =
pyutils-unusedcode --exclude-function-prefixes 'process_webhook'

[testenv:pytest]
deps =
poetry
commands =
poetry install
poetry run pytest webhook_server_container/tests
52 changes: 46 additions & 6 deletions webhook_server_container/libs/github_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,18 +617,58 @@ def assign_reviewers(self) -> None:
self.pull_request.create_issue_comment(f"{reviewer} can not be added as reviewer. {ex}")

def get_size(self) -> str:
"""Calculate size label based on additions and deletions."""
"""Calculates size label based on additions and deletions."""

size = self.pull_request.additions + self.pull_request.deletions
prefixes = ["XS", "S", "M", "L", "XL", "XXL"]
for prefix in prefixes:
if size < 20 * (prefix[:-1].upper() == "S") + 10:
return f"{SIZE_LABEL_PREFIX}{prefix}"

return ""
# Define label thresholds in a more readable way
threshold_sizes = [20, 50, 100, 300, 500]
prefixes = ["XS", "S", "M", "L", "XL"]

for i, size_threshold in enumerate(threshold_sizes):
if size < size_threshold:
_label = prefixes[i]
return f"{SIZE_LABEL_PREFIX}{_label}"

return f"{SIZE_LABEL_PREFIX}XXL"

# def get_size(self) -> str:
# """Calculate size label based on additions and deletions."""
# size: int = self.pull_request.additions + self.pull_request.deletions
# if size < 20:
# _label = "XS"
#
# elif size < 50:
# _label = "S"
#
# elif size < 100:
# _label = "M"
#
# elif size < 300:
# _label = "L"
#
# elif size < 500:
# _label = "XL"
#
# else:
# _label = "XXL"
#
# return f"{SIZE_LABEL_PREFIX}{_label}"
# # size = self.pull_request.additions + self.pull_request.deletions
# # prefixes = ["XS", "S", "M", "L", "XL", "XXL"]
# # for prefix in prefixes:
# # if size < 20 * (prefix[:-1].upper() == "S") + 10:
# # return f"{SIZE_LABEL_PREFIX}{prefix}"
# #
# # return ""

def add_size_label(self) -> None:
"""Add a size label to the pull request based on its additions and deletions."""
size_label = self.get_size()
if not size_label:
self.logger.debug(f"{self.log_prefix} Size label not found")
return

if size_label in self.pull_request_labels_names():
return

Expand Down
92 changes: 92 additions & 0 deletions webhook_server_container/tests/manifests/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
log-level: INFO # Set global log level, change take effect immediately without server restart
log-file: webhook-server.log # Set global log file, change take effect immediately without server restart

github-app-id: 123456 # GitHub app id
github-toekns:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typo in 'github-tokens' key

There's a typo in the key "github-toekns".

Please correct it to "github-tokens":

-github-toekns:
+github-tokens:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
github-toekns:
github-tokens:

- <GITHIB TOKEN1>
- <GITHIB TOKEN2>
Comment thread
myakove marked this conversation as resolved.

webhook_ip: <HTTP://IP OR URL:PORT>
Comment thread
myakove marked this conversation as resolved.

docker: # Used to pull images from docker.io
username: <username>
password: <password>
Comment thread
myakove marked this conversation as resolved.

default-status-checks:
- "WIP"
- "dpulls"
- "can-be-merged"

auto-verified-and-merged-users:
- "renovate[bot]"
- "pre-commit-ci[bot]"

jira:
server: <JIRA URL>
project: <PROJECT KEY>
token: <JIRA TOKEN>
user-mapping:
<GITHUB USER>: <JIRA USER> # if github user is not the same as jira

repositories:
test-repo:
name: my-org/test-repo
log-level: DEBUG # Override global log-level for repository
log-file: test-repo.log # Override global log-file for repository
slack_webhook_url: <Slack webhook url> # Send notification to slack on several operations
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security concern: Slack webhook URL exposed

The Slack webhook URL is exposed in plain text. This could be a security risk if the configuration file is compromised.

Consider using an environment variable for the Slack webhook URL:

slack_webhook_url: ${SLACK_WEBHOOK_URL}

verified_job: true
pypi:
token: <PYPI TOKEN>
Comment on lines +38 to +39
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security concern: Multiple exposed sensitive tokens

Several sensitive tokens and credentials are exposed in plain text throughout the repository-specific configuration. This includes PyPI token, container credentials, GitHub tokens, and Jira token.

Replace all sensitive information with environment variables or use a secure secret management system. For example:

pypi:
  token: ${PYPI_TOKEN}

container:
  username: ${CONTAINER_USERNAME}
  password: ${CONTAINER_PASSWORD}

github-tokens:
  - ${GITHUB_TOKEN1}
  - ${GITHUB_TOKEN2}

jira:
  token: ${JIRA_TOKEN}

Also applies to: 62-64, 76-78, 87-89


events: # To listen to all events do not send events
- push
- pull_request
- issue_comment
- check_run
- pull_request_review
tox:
main: all # Run all tests in tox.ini when pull request parent branch is main
dev: testenv1,testenv2 # Run testenv1 and testenv2 tests in tox.ini when pull request parent branch is dev

pre-commit: true # Run pre-commit check

protected-branches:
dev: []
main: # set [] in order to set all defaults run included
include-runs:
- "pre-commit.ci - pr"
- "WIP"
exclude-runs:
- "SonarCloud Code Analysis"
container:
username: <registry username>
password: <registry_password>
repository: <registry_repository_full_path>
tag: <image_tag>
release: true # Push image to registry on new release with release as the tag
build-args: # build args to send to podman build command
- my-build-arg1=1
- my-build-arg2=2
args: # args to send to podman build command
- --format docker

Comment on lines +61 to +72
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security concern and clarity improvements for container configuration

  1. The container username and password are exposed in plain text, which is a security risk.

  2. The configuration could benefit from comments explaining the purpose of certain settings.

  3. Replace sensitive information with environment variables:

container:
  username: ${CONTAINER_REGISTRY_USERNAME}
  password: ${CONTAINER_REGISTRY_PASSWORD}
  1. Add comments to explain the purpose of certain settings:
container:
  # ... (username and password as above)
  repository: <registry_repository_full_path>
  tag: <image_tag>
  release: true  # Push image to registry on new release, using the release as the tag
  build-args:  # Arguments passed to the container build process
    - my-build-arg1=1
    - my-build-arg2=2
  args:  # Additional arguments for the podman build command
    - --format docker  # Ensure the built image is compatible with Docker

These changes will improve security and make the configuration more self-explanatory.

auto-verified-and-merged-users: # override auto verified users per repository
- "my[bot]"

github-tokens: # override GitHub tokens per repository
- <GITHUB TOKEN1>
- <GITHUB TOKEN2>

can-be-merged-required-labels: # check for extra labels to set PR as can be merged
- my-label1
- my-label2

jira-tracking: true

jira: # override Jira global settings
server: <JIRA URL>
project: <PROJECT KEY>
token: <JIRA TOKEN>
epic: <EPIC KEY> # Optional
user-mapping:
<GITHUB USER>: <JIRA USER> # if github user is not the same as jira
Comment thread
myakove marked this conversation as resolved.
52 changes: 52 additions & 0 deletions webhook_server_container/tests/test_github_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import pytest
from starlette.datastructures import Headers

from simple_logger.logger import logging
from stringcolor.ops import os
from webhook_server_container.libs.github_api import ProcessGithubWehook
from webhook_server_container.utils.constants import SIZE_LABEL_PREFIX


class Repository:
def __init__(self):
self.name = "test-repo"


class PullRequest:
def __init__(self, additions: int, deletions: int):
self.additions = additions
self.deletions = deletions


@pytest.fixture(scope="function")
def process_github_webhook(mocker):
base_import_path = "webhook_server_container.libs.github_api"
os.environ["WEBHOOK_SERVER_DATA_DIR"] = "webhook_server_container/tests/manifests"

mocker.patch(f"{base_import_path}.get_repository_github_app_api", return_value=True)
mocker.patch("github.AuthenticatedUser", return_value=True)
mocker.patch(f"{base_import_path}.get_api_with_highest_rate_limit", return_value=("API", "TOKEN"))
mocker.patch(f"{base_import_path}.get_github_repo_api", return_value=Repository())

return ProcessGithubWehook(
{"repository": {"name": Repository().name}}, Headers({"X-GitHub-Event": "test-event"}), logging.getLogger()
)


@pytest.mark.parametrize(
"additions, deletions, expected_label",
[
(0, 0, "XS"),
(18, 1, "XS"),
(48, 1, "S"),
(98, 1, "M"),
(298, 1, "L"),
(498, 1, "XL"),
(1000, 1, "XXL"),
],
)
def test_get_size_thresholds(process_github_webhook, additions, deletions, expected_label):
process_github_webhook.pull_request = PullRequest(additions=additions, deletions=deletions)
result = process_github_webhook.get_size()

assert result == f"{SIZE_LABEL_PREFIX}{expected_label}"
Comment thread
myakove marked this conversation as resolved.
Loading