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
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2026 The Snakemake team

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
8 changes: 4 additions & 4 deletions docs/intro.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
A Snakemake logger plugin that reports to the Github commit status.
The plugin assumes that it is used in combination with working directories that are controlled by git and associated to a Github repository.
It then reports logging events to the Github status API, such that Github displays the status of workflow runs attached to the current commit.
Github's status markers (running, success, failed) are thereby used to represent the state of the workflow execution, while the status messages are used to report on the number of completed and failed jobs.
A Snakemake logger plugin that reports to the Github commit status.
The plugin assumes that it is used in combination with working directories that are controlled by git and associated to a Github repository.
It then reports logging events to the Github status API, such that Github displays the status of workflow runs attached to the current commit.
Github's status markers (running, success, failed) are thereby used to represent the state of the workflow execution, while the status messages are used to report on the number of completed and failed jobs.
31 changes: 22 additions & 9 deletions src/snakemake_logger_plugin_github_status/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from dataclasses import dataclass, field
import time
from typing import Dict
from typing import Optional
Expand All @@ -12,6 +13,18 @@
from snakemake_interface_logger_plugins.base import LogHandlerBase
from snakemake_interface_logger_plugins.common import LogEvent
from snakemake_interface_common.exceptions import WorkflowError
from snakemake_interface_logger_plugins.settings import LogHandlerSettingsBase


@dataclass
class LogHandlerSettings(LogHandlerSettingsBase):
run_name: Optional[str] = field(
default=None,
metadata={
"help": "Name for the current workflow run. "
"This is used to identify the workflow run in the GitHub status.",
},
)


class LogHandler(LogHandlerBase):
Expand All @@ -31,15 +44,11 @@ def __post_init__(self) -> None:
self._github_repo_name = "/".join(
self._repo.remotes.origin.url.rstrip(".git").split(":")[1].split("/")[-2:]
)
self._repo.remotes.origin.fetch()
branch = self._repo.active_branch
tracking_branch = branch.tracking_branch()
if tracking_branch is None:
raise WorkflowError(
f"No tracking branch of current git branch {branch}. Make sure that your local repo is pushed."
)

self._github_sha = tracking_branch.commit.hexsha
# Use the currently checked-out commit. This works in normal branches and in
# GitHub Actions where the checkout is often in detached HEAD state.
self._github_sha = self._repo.head.commit.hexsha

self._errors: Dict[str, int] = defaultdict(int)
self._progress_done: int = 0
self._progress_total: Optional[int] = None
Expand Down Expand Up @@ -140,6 +149,10 @@ def emit(self, record: LogRecord) -> None:
# Exception: we always emit on "success"
return

context = "snakemake"
if self.settings.run_name:
context += f": {self.settings.run_name}"

self._last_emit_timestamp = time.time()
res = requests.post(
f"https://api.github.com/repos/{self._github_repo_name}/statuses/{self._github_sha}",
Expand All @@ -150,7 +163,7 @@ def emit(self, record: LogRecord) -> None:
},
json={
"state": self.state,
"context": "snakemake",
"context": context,
"description": description,
},
)
Expand Down
12 changes: 7 additions & 5 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from snakemake_logger_plugin_github_status import LogHandlerSettings
from snakemake_logger_plugin_github_status import LogHandler
from snakemake_interface_logger_plugins.tests import TestLogHandlerBase


class TestPlugin(TestLogHandlerBase):
"""Concrete test using the actual rich plugin to verify the abstract test class works."""

__test__ = True

def get_log_handler_cls(self):
"""Return the log handler class."""
return LogHandler

def get_log_handler_settings(self):
"""Return the settings with default values for testing."""
return None
return LogHandlerSettings()


class TestPluginWithRunName(TestPlugin):
def get_log_handler_settings(self):
return LogHandlerSettings(run_name="test_run")
Loading