X Tutup
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
ac48531
feat(release-notes): add PyPI reference link for project in default t…
codejedi365 Dec 24, 2024
8269d70
feat(release): add issue resolution announcement default template
codejedi365 Dec 24, 2024
b52127e
feat(release): add PR publish announcement default template
codejedi365 Dec 24, 2024
7efb356
test(hvcs): remove obsolete requests-based tests from github suite
lilfetz22 Jan 10, 2026
d59d4ab
feat(hvcs): add issue announcement and labeling methods to Github class
lilfetz22 Jan 10, 2026
1aa4ead
feat(cli): integrate release announcements into version command
lilfetz22 Jan 10, 2026
b1adcc6
fix(cli): pass release object to announcement templates
lilfetz22 Jan 10, 2026
72e6753
style: apply ruff formatting to github.py and tests
lilfetz22 Jan 10, 2026
43ba440
fix(cli): fix mypy type errors in main.py and version.py
lilfetz22 Jan 10, 2026
0467b24
fix(cli): resolve type mismatch and missing template filters in annou…
lilfetz22 Jan 10, 2026
cffca63
fix(templates): remove invalid macro import of format_link_reference
lilfetz22 Jan 11, 2026
56658b0
test(e2e): fix changelog release notes test for PyGithub integration
lilfetz22 Jan 11, 2026
91fd7f7
Merge branch 'master' into feat/pygithub-migration-and-announcements
lilfetz22 Jan 19, 2026
9c96b98
fix(cli/generate-config): stop emitting deprecated changelog_file in …
lilfetz22 Jan 19, 2026
1dd193a
fix(config): suppress changelog.deprecation warning when value is not…
lilfetz22 Jan 19, 2026
dc382e8
test(e2e/generate-config): expect default config without deprecated c…
lilfetz22 Jan 19, 2026
83c11bf
test(cli/config): align default toml dump and preserve system PATH in…
lilfetz22 Jan 19, 2026
90f2385
chore(tests): add captured pytest output to test_results.txt for loca…
lilfetz22 Jan 19, 2026
a43ad6b
docs(commit-parsing): clarify supported issue footer formats (with an…
lilfetz22 Jan 24, 2026
10fc3ba
feat(announcements): fall back to default embedded templates for issu…
lilfetz22 Jan 24, 2026
ab8d603
fix(commit-parser/angular): accept issue footers without colon
lilfetz22 Jan 24, 2026
c7c8727
fix(commit-parser/conventional): accept issue footers without colon
lilfetz22 Jan 24, 2026
6a21d0a
fix(commit-parser/emoji): accept issue footers without colon
lilfetz22 Jan 24, 2026
0abab00
fix(commit-parser/scipy): accept issue footers without colon
lilfetz22 Jan 24, 2026
b55197d
fix(cli/version): robust shell invocation, env merging, and error han…
lilfetz22 Jan 26, 2026
e9d66ba
fix(hvcs/github): handle AssetUploadError when uploading assets and g…
lilfetz22 Jan 26, 2026
f1d5ff6
test(version/declarations): normalize line endings for cross-platform…
lilfetz22 Jan 26, 2026
aa3da3b
test(version/declarations): use relative paths for cross-platform sta…
lilfetz22 Jan 26, 2026
da9170c
test(version/declarations): avoid absolute paths in TOML tests for Wi…
lilfetz22 Jan 26, 2026
6e198df
chore(tests): update binary test results to reflect recent changes
lilfetz22 Feb 28, 2026
10a953b
feat(changelog): add include_pypi_link field to ReleaseNotesContext
lilfetz22 Mar 2, 2026
68e5271
feat(cli): propagate include_pypi_link parameter to generate_release_…
lilfetz22 Mar 2, 2026
c3e74a1
fix(parser): require colon after closure keyword in conventional parser
lilfetz22 Mar 2, 2026
3e65c5f
fix(parser): enforce colon in closure regex for scipy parser
lilfetz22 Mar 2, 2026
4c30d27
fix(parser): avoid git subprocess on deep_copy_commit to reduce Windo…
lilfetz22 Mar 2, 2026
83a0fc2
feat(template): make PyPI link section conditional in release notes
lilfetz22 Mar 2, 2026
fc0fa84
chore(test): refresh test_results.txt with latest failure output
lilfetz22 Mar 2, 2026
87aafd9
fix(tests): add fallback worker_id fixture when pytest-xdist not active
lilfetz22 Mar 2, 2026
f37c6b1
test(changelog): add test for include_pypi_link and normalize line en…
lilfetz22 Mar 2, 2026
2ee03d2
docs: add TEST_FAILURE_GROUPS.md with failure categorization and fix …
lilfetz22 Mar 2, 2026
6089517
chore: add parse_errors.py utility for converting XML test results to…
lilfetz22 Mar 2, 2026
96849b7
chore(test): add raw XML test results for debugging failures
lilfetz22 Mar 2, 2026
cafd199
fix(parser): update regex to require a colon after issue keywords
lilfetz22 Mar 7, 2026
f66de84
chore(test_results): removal of test results files
lilfetz22 Mar 7, 2026
2b3b9c8
refactor(tests): extract PostOnlyMocker class and use patch.object in…
lilfetz22 Mar 8, 2026
c956a2b
docs(copilot-instructions): add 100-char header limit and no-skip hoo…
lilfetz22 Mar 8, 2026
1421086
fix(util): enhance remove_dir_tree to handle directories and improve …
lilfetz22 Mar 8, 2026
18d18a1
refactor(tests): improve line ending normalization and readability in…
lilfetz22 Mar 8, 2026
e4307fc
fix(fixtures): synchronize cached repo lifecycle across xdist workers
lilfetz22 Mar 8, 2026
2525cb6
fix(fixtures): clear post history when resetting e2e post mocker
lilfetz22 Mar 8, 2026
3814492
fix(fixtures): gate fixture PyPI link block behind include_pypi_link
lilfetz22 Mar 8, 2026
73eea58
test(fixtures): add regression coverage for xdist repo cache synchron…
lilfetz22 Mar 8, 2026
d469c30
test: fix e2e test suite regressions after pygithub migration
lilfetz22 Mar 9, 2026
da9a9f2
chore(tests): resolve mypy typing and formating bugs
lilfetz22 Mar 9, 2026
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
8 changes: 8 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ and is not present in the default branch.
[optional footer(s)]
```

The header line (`<type>(<scope>): <summary>`) must not exceed **100 characters**.
This limit is enforced by commitlint in CI and will cause the pipeline to fail.
Always check the length of the header before committing.

Scopes by the specification are optional but for this project, they are required and
only by exception can they be omitted.

Expand Down Expand Up @@ -548,3 +552,7 @@ itself to perform the release steps. The release process includes:
versioning. Make as few breaking changes as possible by adding backwards compatibility
and if you do make a breaking change, be sure to include a detailed description in the
`BREAKING CHANGE` footer of the commit message.

- Never disable or bypass pre-commit hooks (e.g. do not use `git commit --no-verify`).
All hooks must remain active and pass before committing. If a hook is failing, fix the
underlying issue rather than skipping the check.
18 changes: 16 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
default_language_version:
python: python3

exclude: "^CHANGELOG.md$"
exclude: "^CHANGELOG.rst$"

repos:
# Meta hooks
Expand Down Expand Up @@ -56,9 +56,22 @@ repos:
additional_dependencies:
- "pydantic>=2,<3"
- "types-requests"
- "types-Deprecated"
- "types-pyyaml"
- "click~=8.1"
- "gitpython~=3.0"
- "jinja2~=3.1"
- "PyGithub~=2.0"
- "python-gitlab>=4.0.0,<7.0.0"
- "tomlkit~=0.13.0"
- "rich~=14.0"
- "shellingham~=1.5"
- "importlib-resources~=6.0"
- "click-option-group~=0.5"
log_file: "mypy.log"
files: "^(src|tests)/.*"
pass_filenames: false
args: ["src"]

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
Expand All @@ -80,8 +93,9 @@ repos:
- --min-confidence
- "100"
- --sort-by-size
- "semantic_release"
- "src/semantic_release"
- "tests"
pass_filenames: false

- repo: https://github.com/pycqa/bandit
rev: 1.7.8
Expand Down
25 changes: 13 additions & 12 deletions docs/concepts/commit_parsing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,12 @@ Common Issue Identifier Detection

All of the PSR built-in parsers implement common issue identifier detection logic,
which is similar to many VCS platforms such as GitHub, GitLab, and BitBucket. The
parsers will look for common issue closure text prefixes in the `Git Trailer format`_
in the commit message to identify and extract issue numbers. The detection logic is
not strict to any specific issue tracker as we try to provide a flexible approach
to identifying issue numbers but in order to be flexible, it is **required** to the
use the `Git Trailer format`_ with a colon (``:``) as the token separator.
parsers will look for common issue closure text prefixes in commit message footers
to identify and extract issue numbers. The detection logic is not strict to any specific
issue tracker as we try to provide a flexible approach to identifying issue numbers.
PSR supports the `Git Trailer format`_ with a colon (``:``) as the token separator,
as well as the more casual format without a colon (e.g., ``Closes #123`` or ``Closes: #123``)
to match common VCS platform conventions.

PSR attempts to support all variants of issue closure text prefixes, but not all will work
for your VCS. PSR supports the following case-insensitive prefixes and their conjugations
Expand All @@ -466,13 +467,13 @@ the need of extra git trailers (although PSR does support multiple git trailers)
various list formats which can be used to identify more than one issue in a list. This format
will not necessarily work on your VCS. PSR currently support the following list formats:

- comma-separated (ex. ``Closes: #123, #456, #789``)
- space-separated (ex. ``resolve: #123 #456 #789``)
- semicolon-separated (ex. ``Fixes: #123; #456; #789``)
- slash-separated (ex. ``close: #123/#456/#789``)
- ampersand-separated (ex. ``Implement: #123 & #789``)
- and-separated (ex. ``Resolve: #123 and #456 and #789``)
- mixed (ex. ``Closed: #123, #456, and #789`` or ``Fixes: #123, #456 & #789``)
- comma-separated (ex. ``Closes #123, #456, #789`` or ``Closes: #123, #456, #789``)
- space-separated (ex. ``resolve #123 #456 #789`` or ``resolve: #123 #456 #789``)
- semicolon-separated (ex. ``Fixes #123; #456; #789`` or ``Fixes: #123; #456; #789``)
- slash-separated (ex. ``close #123/#456/#789`` or ``close: #123/#456/#789``)
- ampersand-separated (ex. ``Implement #123 & #789`` or ``Implement: #123 & #789``)
- and-separated (ex. ``Resolve #123 and #456 and #789`` or ``Resolve: #123 and #456 and #789``)
- mixed (ex. ``Closed #123, #456, and #789`` or ``Fixes #123, #456 & #789`` or with colons)

All the examples above use the most common issue number prefix (``#``) but PSR is flexible
to support other prefixes used by VCS platforms or issue trackers such as JIRA (ex. ``ABC-###``).
Expand Down
45 changes: 45 additions & 0 deletions parse_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import xml.etree.ElementTree as ET # noqa: S314 # safe use in offline parsing of test results


def parse_failures() -> None:
# return type is None since this is a standalone utility

try:
tree = ET.parse("test_results.xml") # noqa: S314
root = tree.getroot()

with open("test_results.txt", "w", encoding="utf-8") as f:
failure_count = 0

for testcase in root.iter("testcase"):
# Look for failure or error tags inside the testcase
failure = testcase.find("failure")
error = testcase.find("error")

issue = failure if failure is not None else error

if issue is not None:
failure_count += 1
file_path = testcase.get("file")
test_name = testcase.get("name")
error_msg = issue.get("message")
# Get the detailed traceback text
traceback = issue.text if issue.text else "No traceback available"

f.write(f"--- FAILURE #{failure_count} ---\n")
f.write(f"FILE: {file_path}\n")
f.write(f"TEST: {test_name}\n")
f.write(f"MESSAGE: {error_msg}\n")
f.write(f"DETAILS:\n{traceback.strip()}\n")
f.write("\n" + "=" * 40 + "\n\n")

print(f"Done! Found {failure_count} failures. Saved to 'test_results.txt'.") # noqa: T201

except FileNotFoundError:
print("Error: Could not find 'test_results.xml'. Did the tests finish running?") # noqa: T201
except Exception as e: # noqa: BLE001,S314
print(f"An error occurred: {e}") # noqa: T201


if __name__ == "__main__":
parse_failures()
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies = [
"gitpython ~= 3.0",
"requests ~= 2.25",
"jinja2 ~= 3.1",
"PyGithub ~= 2.0",
"python-gitlab >= 4.0.0, < 7.0.0",
"tomlkit ~= 0.13.0",
"dotty-dict ~= 1.3",
Expand Down Expand Up @@ -406,7 +407,7 @@ section-order = [
sections = { "tests" = ["tests"] }

[tool.vulture]
ignore_names = ["change_to_ex_proj_dir", "init_example_project"]
ignore_names = ["change_to_ex_proj_dir", "init_example_project", "pluginmanager", "base_repo_def", "init_example_monorepo"]

[tool.semantic_release]
add_partial_tags = true
Expand Down
1 change: 1 addition & 0 deletions src/semantic_release/changelog/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ReleaseNotesContext:
release: Release
mask_initial_release: bool
license_name: str
include_pypi_link: bool = False
filters: tuple[Callable[..., Any], ...] = ()

def bind_to_environment(self, env: Environment) -> Environment:
Expand Down
2 changes: 2 additions & 0 deletions src/semantic_release/cli/changelog_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ def generate_release_notes(
style: str,
mask_initial_release: bool,
license_name: str = "",
include_pypi_link: bool = False,
) -> str:
users_tpl_file = template_dir / DEFAULT_RELEASE_NOTES_TPL_FILE

Expand Down Expand Up @@ -257,6 +258,7 @@ def generate_release_notes(
release=release,
mask_initial_release=mask_initial_release,
license_name=license_name,
include_pypi_link=include_pypi_link,
filters=(
*hvcs_client.get_changelog_context_filters(),
create_pypi_url,
Expand Down
7 changes: 6 additions & 1 deletion src/semantic_release/cli/commands/generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ def generate_config(
# due to possible IntEnum values (which are not supported by tomlkit.dumps, see sdispater/tomlkit#237),
# we must ensure the transformation of the model to a dict uses json serializable values
config_dct = {
"semantic_release": RawConfig().model_dump(mode="json", exclude_none=True)
"semantic_release": RawConfig().model_dump(
mode="json",
exclude_none=True,
# Drop deprecated changelog option to avoid emitting warnings in defaults
exclude={"changelog": {"changelog_file"}},
)
}

if is_pyproject_toml:
Expand Down
7 changes: 1 addition & 6 deletions src/semantic_release/cli/commands/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import logging
from enum import Enum

# from typing import TYPE_CHECKING
import click
from rich.console import Console
from rich.logging import RichHandler
Expand All @@ -17,10 +16,6 @@
from semantic_release.cli.util import rprint
from semantic_release.enums import SemanticReleaseLogLevels

# if TYPE_CHECKING:
# pass


FORMAT = "%(message)s"
LOG_LEVELS = [
SemanticReleaseLogLevels.WARNING,
Expand All @@ -30,7 +25,7 @@
]


class Cli(click.MultiCommand):
class Cli(click.MultiCommand): # type: ignore[misc, valid-type]
"""Root MultiCommand for the semantic-release CLI"""

class SubCmds(Enum):
Expand Down
Loading
Loading
X Tutup