diff --git a/README.md b/README.md index 45b462d..378a21b 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,26 @@ CLI flags (`--enable`, `--disable`, `--scopes`, `--require-scope`, `--types`, `--max-subject-length`, `--min-description-length`, `--require-trailer`) take full precedence and ignore config file values when provided. +### Environment variables + +| Variable | Default | Description | +| -------------------------- | ------- | -------------------------------------------- | +| `COMMIT_GUARD_GIT_TIMEOUT` | `10` | Timeout in seconds for git subprocess calls. | + +```bash +COMMIT_GUARD_GIT_TIMEOUT=30 commit-guard --range origin/main..HEAD +``` + +In GitHub Actions, set it at the step or job level: + +```yaml +- uses: benner/commit-guard@v0.14.1 + env: + COMMIT_GUARD_GIT_TIMEOUT: 30 + with: + range: ${{ env.PR_BASE }}..${{ env.PR_HEAD }} +``` + ### Checking a range of commits Use `--range` to check all commits in a revision range. All commits are diff --git a/src/git_commit_guard/__init__.py b/src/git_commit_guard/__init__.py index 5705048..e1af9e4 100644 --- a/src/git_commit_guard/__init__.py +++ b/src/git_commit_guard/__init__.py @@ -1,4 +1,5 @@ import json +import os import re import subprocess import sys @@ -43,6 +44,10 @@ GIT_TIMEOUT = 10 +def _git_timeout(): + return int(os.environ.get("COMMIT_GUARD_GIT_TIMEOUT", GIT_TIMEOUT)) + + class Check(StrEnum): SUBJECT = "subject" IMPERATIVE = "imperative" @@ -228,7 +233,7 @@ def check_signature(rev, result): capture_output=True, text=True, check=False, - timeout=GIT_TIMEOUT, + timeout=_git_timeout(), ) if proc.returncode != 0: result.error("commit is not signed (GPG/SSH)", check=Check.SIGNATURE) @@ -245,7 +250,7 @@ def _get_message(rev): ["git", "log", "-1", "--format=%B", rev], # noqa: S607 text=True, stderr=subprocess.PIPE, - timeout=GIT_TIMEOUT, + timeout=_git_timeout(), ).strip() except subprocess.CalledProcessError as e: stderr = e.stderr.strip() @@ -264,7 +269,7 @@ def _get_range_revs(rev_range, *, include_merges=False): cmd, text=True, stderr=subprocess.PIPE, - timeout=GIT_TIMEOUT, + timeout=_git_timeout(), ).strip() except subprocess.CalledProcessError as e: sys.exit(f"git error: {e.stderr.strip()}") diff --git a/tests/test_git_commit_guard.py b/tests/test_git_commit_guard.py index 5b04ef4..18129f2 100644 --- a/tests/test_git_commit_guard.py +++ b/tests/test_git_commit_guard.py @@ -6,6 +6,7 @@ import pytest from git_commit_guard import ( + GIT_TIMEOUT, MAX_SUBJECT_LEN, TYPES, Result, @@ -13,6 +14,7 @@ _ensure_nltk_data, _get_message, _get_range_revs, + _git_timeout, _load_config, _parse_checks, _parse_config_checks, @@ -579,6 +581,16 @@ def test_cli_overrides_config(self): assert result == 10 +class TestGitTimeout: + def test_default(self, monkeypatch): + monkeypatch.delenv("COMMIT_GUARD_GIT_TIMEOUT", raising=False) + assert _git_timeout() == GIT_TIMEOUT + + def test_env_var(self, monkeypatch): + monkeypatch.setenv("COMMIT_GUARD_GIT_TIMEOUT", "30") + assert _git_timeout() == 30 + + class TestResolveTypes: def test_defaults_when_no_config_or_flag(self): assert _resolve_types(Namespace(types=None), {}) == TYPES