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
43 changes: 18 additions & 25 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ EXPOSE 5000
ENV USERNAME="podman"
ENV HOME_DIR="/home/$USERNAME"
ENV BIN_DIR="$HOME_DIR/.local/bin"
ENV PATH="$PATH:$BIN_DIR"
ENV DATA_DIR="$HOME_DIR/data"
ENV APP_DIR="$HOME_DIR/github-webhook-server"
ENV PATH="$PATH:$BIN_DIR" \
DATA_DIR="$HOME_DIR/data" \
APP_DIR="$HOME_DIR/github-webhook-server"

RUN systemd-machine-id-setup

RUN dnf -y install dnf-plugins-core \
&& dnf -y update \
&& dnf -y install \
RUN dnf --nodocs --setopt=install_weak_deps=False --disable-repo=fedora-cisco-openh264 -y install dnf-plugins-core \
&& dnf --nodocs --setopt=install_weak_deps=False --disable-repo=fedora-cisco-openh264 -y update \
&& dnf --nodocs --setopt=install_weak_deps=False --disable-repo=fedora-cisco-openh264 -y install \
git \
unzip \
gcc \
Expand All @@ -31,7 +31,7 @@ RUN dnf -y install dnf-plugins-core \
which \
tini \
&& dnf clean all \
&& rm -rf /var/cache /var/log/dnf* /var/log/yum.*
&& rm -rf /var/cache /var/log/dnf* /var/log/yum.* /var/lib/dnf /var/log/dnf.* /var/log/hawkey.log


RUN mkdir -p $BIN_DIR \
Expand All @@ -49,29 +49,22 @@ RUN usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USERNAME \
USER $USERNAME
WORKDIR $HOME_DIR

ENV UV_PYTHON=python3.13
ENV UV_COMPILE_BYTECODE=1
ENV UV_NO_SYNC=1
ENV UV_CACHE_DIR=${APP_DIR}/.cache
ENV PYTHONUNBUFFERED=1
ENV UV_PYTHON=python3.13 \
UV_COMPILE_BYTECODE=1 \
UV_NO_SYNC=1 \
UV_CACHE_DIR=${APP_DIR}/.cache \
PYTHONUNBUFFERED=1

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx ${BIN_DIR}/
RUN uv tool install pre-commit && uv tool install poetry && uv tool install prek
RUN uv tool install pre-commit && uv tool install poetry && uv tool install prek && uv tool install tox

RUN set -x \
&& curl https://mirror.openshift.com/pub/openshift-v4/clients/rosa/latest/rosa-linux.tar.gz --output $BIN_DIR/rosa-linux.tar.gz \
&& tar xvf $BIN_DIR/rosa-linux.tar.gz \
&& mv rosa $BIN_DIR/rosa \
RUN set -ex \
&& curl --fail -vL https://mirror.openshift.com/pub/openshift-v4/clients/rosa/latest/rosa-linux.tar.gz | tar -C $BIN_DIR -xzvf - rosa \
&& chmod +x $BIN_DIR/rosa \
&& rm -rf $BIN_DIR/rosa-linux.tar.gz \
&& curl -L https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64 >$BIN_DIR/regctl \
&& curl --fail -vL https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64 -o $BIN_DIR/regctl \
&& chmod +x $BIN_DIR/regctl \
&& curl -L https://github.com/mislav/hub/releases/download/v2.14.2/hub-linux-amd64-2.14.2.tgz --output ${BIN_DIR}/hub-linux-amd64.tgz \
&& tmp_dir="$(mktemp -d)" \
&& tar xvf ${BIN_DIR}/hub-linux-amd64.tgz -C "${tmp_dir}" \
&& mv "${tmp_dir}"/hub-linux-amd64-2.14.2/bin/hub ${BIN_DIR}/hub \
&& chmod +x ${BIN_DIR}/hub \
&& rm -rf "${tmp_dir}" ${BIN_DIR}/hub-linux-amd64.tgz
&& curl --fail -vL https://github.com/mislav/hub/releases/download/v2.14.2/hub-linux-amd64-2.14.2.tgz | tar --strip-components=2 -C $BIN_DIR -xzvf - '*/bin/hub' \
&& chmod +x $BIN_DIR/hub
Comment thread
coderabbitai[bot] marked this conversation as resolved.

WORKDIR $APP_DIR

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ packages = ["webhook_server"]
[project]
name = "github-webhook-server"
version = "4.0.0"
requires-python = ">=3.12"
requires-python = "==3.13.*"
description = "A webhook server to manage Github repositories and pull requests."
readme = "README.md"
license = "Apache-2.0"
Expand Down
384 changes: 1 addition & 383 deletions uv.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion webhook_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def require_log_server_enabled() -> None:


@asynccontextmanager
async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]:
async def lifespan(_app: FastAPI) -> AsyncGenerator[None]:
global _lifespan_http_client
_lifespan_http_client = httpx.AsyncClient(timeout=HTTP_TIMEOUT_SECONDS)

Expand Down
2 changes: 1 addition & 1 deletion webhook_server/libs/handlers/runner_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def _checkout_worktree(
is_merged: bool = False,
checkout: str = "",
tag_name: str = "",
) -> AsyncGenerator[tuple[bool, str, str, str], None]:
) -> AsyncGenerator[tuple[bool, str, str, str]]:
"""Create worktree from existing clone for handler operations.

Uses centralized clone from github_webhook.clone_repo_dir and creates
Expand Down
4 changes: 2 additions & 2 deletions webhook_server/libs/log_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def parse_log_file(self, file_path: Path) -> list[LogEntry]:

return entries

async def tail_log_file(self, file_path: Path, follow: bool = True) -> AsyncGenerator[LogEntry, None]:
async def tail_log_file(self, file_path: Path, follow: bool = True) -> AsyncGenerator[LogEntry]:
"""
Tail a log file and yield new LogEntry objects as they are added.

Expand Down Expand Up @@ -341,7 +341,7 @@ async def tail_log_file(self, file_path: Path, follow: bool = True) -> AsyncGene
# Not following, exit when no more data
break

async def monitor_log_directory(self, log_dir: Path, pattern: str = "*.log") -> AsyncGenerator[LogEntry, None]:
async def monitor_log_directory(self, log_dir: Path, pattern: str = "*.log") -> AsyncGenerator[LogEntry]:
"""
Monitor a directory for log files and yield new entries from all files.

Expand Down
14 changes: 5 additions & 9 deletions webhook_server/tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def server_envs() -> dict[str, str]:


@pytest.fixture(scope="session")
def github_webhook_cleanup(server_envs: dict[str, str]) -> Generator[None, None, None]:
def github_webhook_cleanup(server_envs: dict[str, str]) -> Generator[None]:
"""Manages GitHub webhook lifecycle (session-scoped).

This fixture ensures the GitHub webhook is properly cleaned up after all tests complete.
Expand Down Expand Up @@ -162,7 +162,7 @@ def github_webhook_cleanup(server_envs: dict[str, str]) -> Generator[None, None,


@pytest.fixture(scope="session")
def e2e_server(server_envs: dict[str, str], github_webhook_cleanup: None) -> Generator[None, None, None]:
def e2e_server(server_envs: dict[str, str], github_webhook_cleanup: None) -> Generator[None]:
"""Session-scoped fixture that manages E2E testing infrastructure.

This fixture manages the complete E2E testing infrastructure:
Expand Down Expand Up @@ -233,9 +233,7 @@ def test_repository_name(server_envs: dict[str, str]) -> str:


@pytest.fixture(scope="session")
def cloned_test_repo(
tmp_path_factory: pytest.TempPathFactory, test_repository_name: str
) -> Generator[Path, None, None]:
def cloned_test_repo(tmp_path_factory: pytest.TempPathFactory, test_repository_name: str) -> Generator[Path]:
"""Clone test repository to temporary directory (session-scoped).

Args:
Expand Down Expand Up @@ -264,7 +262,7 @@ def cloned_test_repo(


@pytest.fixture(scope="class")
def branch_for_tests(cloned_test_repo: Path, test_repository_name: str) -> Generator[str, None, None]:
def branch_for_tests(cloned_test_repo: Path, test_repository_name: str) -> Generator[str]:
"""Provides a test branch for the current test.

Args:
Expand Down Expand Up @@ -326,9 +324,7 @@ def branch_for_tests(cloned_test_repo: Path, test_repository_name: str) -> Gener


@pytest.fixture(scope="class")
def pr_for_tests(
cloned_test_repo: Path, branch_for_tests: str, test_repository_name: str
) -> Generator[str, None, None]:
def pr_for_tests(cloned_test_repo: Path, branch_for_tests: str, test_repository_name: str) -> Generator[str]:
"""Provides a test PR for the current test.

Args:
Expand Down
2 changes: 1 addition & 1 deletion webhook_server/tests/test_edge_cases_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


@pytest.fixture
def temp_log_file() -> Generator[callable, None, None]:
def temp_log_file() -> Generator[callable]:
"""Fixture that provides a helper function to create temporary log files with content.

Returns a function that takes log content and optional encoding,
Expand Down
4 changes: 2 additions & 2 deletions webhook_server/tests/test_runner_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ def mock_pull_request(self) -> Mock:
return mock_pr

@pytest.fixture(autouse=True)
def patch_check_run_text(self) -> Generator[None, None, None]:
def patch_check_run_text(self) -> Generator[None]:
with patch(
"webhook_server.libs.handlers.check_run_handler.CheckRunHandler.get_check_run_text",
return_value="dummy output",
):
yield

@pytest.fixture(autouse=True)
def patch_shutil_rmtree(self) -> Generator[None, None, None]:
def patch_shutil_rmtree(self) -> Generator[None]:
with patch("shutil.rmtree"):
yield

Expand Down
2 changes: 1 addition & 1 deletion webhook_server/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ async def git_worktree_checkout(
checkout: str,
log_prefix: str,
mask_sensitive: bool = True,
) -> AsyncGenerator[tuple[bool, str, str, str], None]:
) -> AsyncGenerator[tuple[bool, str, str, str]]:
"""Create git worktree for isolated checkout operations.

Creates a temporary worktree from existing cloned repository, allowing
Expand Down
2 changes: 1 addition & 1 deletion webhook_server/web/log_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ def export_logs(
media_type = "application/json"
filename = f"webhook_logs_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json"

def generate() -> Generator[bytes, None, None]:
def generate() -> Generator[bytes]:
yield content.encode("utf-8")

return StreamingResponse(
Expand Down