Public Access
DEVX-106: feat: detect badge commits as automated CI commits
Post-merge / detect-type (push) Successful in 8s
Post-merge / validate-commit-msg (push) Successful in 9s
Post-merge / vikunja (push) Successful in 21s
Post-merge / configure-repo (push) Successful in 13s
Build Images / detect-type (push) Successful in 40s
Post-merge / sync-wiki (push) Successful in 36s
Post-merge / release (push) Successful in 39s
Post-merge / badges (push) Successful in 45s
Post-merge / publish (push) Successful in 18s
Build Images / build-and-push (push) Successful in 3m1s
Build Images / cleanup (push) Successful in 2m47s
Post-merge / detect-type (push) Successful in 8s
Post-merge / validate-commit-msg (push) Successful in 9s
Post-merge / vikunja (push) Successful in 21s
Post-merge / configure-repo (push) Successful in 13s
Build Images / detect-type (push) Successful in 40s
Post-merge / sync-wiki (push) Successful in 36s
Post-merge / release (push) Successful in 39s
Post-merge / badges (push) Successful in 45s
Post-merge / publish (push) Successful in 18s
Build Images / build-and-push (push) Successful in 3m1s
Build Images / cleanup (push) Successful in 2m47s
This commit was merged in pull request #163.
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Detect whether the latest git commit is a release commit.
|
||||
"""Detect whether the latest git commit is an automated CI commit.
|
||||
|
||||
Release commits have the format ``release: vX.Y.Z``.
|
||||
Badge commits have the format ``chore: update badge URLs ... [skip ci]``.
|
||||
Both are generated by CI and should skip post-merge jobs.
|
||||
|
||||
This script writes ``is-release=true`` or ``is-release=false`` to
|
||||
``$GITHUB_OUTPUT`` for use in CI workflow conditionals.
|
||||
|
||||
@@ -21,6 +24,7 @@ from devx.ci._shared import write_github_output
|
||||
from devx.i18n import _
|
||||
|
||||
RELEASE_RE = re.compile(r"^release: v\d+\.\d+\.\d+")
|
||||
BADGE_RE = re.compile(r"^chore: update badge URLs.*\[skip ci\]")
|
||||
|
||||
|
||||
def get_commit_message() -> str:
|
||||
@@ -41,15 +45,29 @@ def is_release_commit(message: str) -> bool:
|
||||
return bool(RELEASE_RE.match(message))
|
||||
|
||||
|
||||
def is_badge_commit(message: str) -> bool:
|
||||
"""Check if a commit message matches the badge commit format."""
|
||||
return bool(BADGE_RE.match(message))
|
||||
|
||||
|
||||
def is_automated_commit(message: str) -> bool:
|
||||
"""Check if a commit is an automated CI commit (release or badge)."""
|
||||
return is_release_commit(message) or is_badge_commit(message)
|
||||
|
||||
|
||||
@click.command()
|
||||
def main() -> None:
|
||||
"""Detect if the latest commit is a release commit and set GITHUB_OUTPUT."""
|
||||
"""Detect if the latest commit is an automated CI commit and set GITHUB_OUTPUT."""
|
||||
msg = get_commit_message()
|
||||
click.echo(_("Commit message: {msg}", msg=msg))
|
||||
is_release = is_release_commit(msg)
|
||||
is_automated = is_automated_commit(msg)
|
||||
write_github_output("is-release", "true" if is_release else "false")
|
||||
write_github_output("is-automated", "true" if is_automated else "false")
|
||||
if is_release:
|
||||
click.echo(_("Release commit — skipping all post-merge jobs."))
|
||||
elif is_automated:
|
||||
click.echo(_("Automated CI commit (badge) — skipping post-merge jobs."))
|
||||
else:
|
||||
click.echo(_("Regular merge commit — running all post-merge jobs."))
|
||||
|
||||
|
||||
@@ -2127,6 +2127,14 @@
|
||||
"ru": "Release commit — skipping all post-merge jobs.",
|
||||
"zh": "Release commit — skipping all post-merge jobs."
|
||||
},
|
||||
"Automated CI commit (badge) — skipping post-merge jobs.": {
|
||||
"bg": "Automated CI commit (badge) — skipping post-merge jobs.",
|
||||
"de": "Automated CI commit (badge) — skipping post-merge jobs.",
|
||||
"en": "Automated CI commit (badge) — skipping post-merge jobs.",
|
||||
"pl": "Automated CI commit (badge) — skipping post-merge jobs.",
|
||||
"ru": "Automated CI commit (badge) — skipping post-merge jobs.",
|
||||
"zh": "Automated CI commit (badge) — skipping post-merge jobs."
|
||||
},
|
||||
"Release creation failed: {error}": {
|
||||
"bg": "Release creation failed: {error}",
|
||||
"de": "Release creation failed: {error}",
|
||||
|
||||
@@ -38,6 +38,31 @@ class TestIsReleaseCommit:
|
||||
assert detect_release_commit.is_release_commit("") is False
|
||||
|
||||
|
||||
class TestIsBadgeCommit:
|
||||
def test_badge_commit(self) -> None:
|
||||
assert detect_release_commit.is_badge_commit("chore: update badge URLs to commit abc123 [skip ci]") is True
|
||||
|
||||
def test_regular_chore(self) -> None:
|
||||
assert detect_release_commit.is_badge_commit("chore: cleanup deps") is False
|
||||
|
||||
def test_empty(self) -> None:
|
||||
assert detect_release_commit.is_badge_commit("") is False
|
||||
|
||||
|
||||
class TestIsAutomatedCommit:
|
||||
def test_release_is_automated(self) -> None:
|
||||
assert detect_release_commit.is_automated_commit("release: v1.0.0 [skip ci]") is True
|
||||
|
||||
def test_badge_is_automated(self) -> None:
|
||||
assert detect_release_commit.is_automated_commit("chore: update badge URLs to commit abc123 [skip ci]") is True
|
||||
|
||||
def test_regular_is_not_automated(self) -> None:
|
||||
assert detect_release_commit.is_automated_commit("OBL-INFRA-363: fix: something") is False
|
||||
|
||||
def test_empty(self) -> None:
|
||||
assert detect_release_commit.is_automated_commit("") is False
|
||||
|
||||
|
||||
class TestWriteGithubOutput:
|
||||
def test_write(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
gh_file = tmp_path / "output.txt"
|
||||
@@ -62,7 +87,26 @@ class TestMain:
|
||||
assert result.exit_code == 0
|
||||
assert "Release commit" in result.output
|
||||
with open(gh_file) as f:
|
||||
assert "is-release=true" in f.read()
|
||||
content = f.read()
|
||||
assert "is-release=true" in content
|
||||
assert "is-automated=true" in content
|
||||
|
||||
def test_badge_commit(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
gh_file = tmp_path / "output.txt"
|
||||
monkeypatch.setenv("GITHUB_OUTPUT", str(gh_file))
|
||||
with patch.object(
|
||||
detect_release_commit,
|
||||
"get_commit_message",
|
||||
return_value="chore: update badge URLs to commit abc123 [skip ci]",
|
||||
):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(detect_release_commit.main, [])
|
||||
assert result.exit_code == 0
|
||||
assert "Automated CI commit" in result.output
|
||||
with open(gh_file) as f:
|
||||
content = f.read()
|
||||
assert "is-release=false" in content
|
||||
assert "is-automated=true" in content
|
||||
|
||||
def test_regular_commit(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
gh_file = tmp_path / "output.txt"
|
||||
@@ -73,4 +117,6 @@ class TestMain:
|
||||
assert result.exit_code == 0
|
||||
assert "Regular merge commit" in result.output
|
||||
with open(gh_file) as f:
|
||||
assert "is-release=false" in f.read()
|
||||
content = f.read()
|
||||
assert "is-release=false" in content
|
||||
assert "is-automated=false" in content
|
||||
|
||||
Reference in New Issue
Block a user