diff --git a/.github/templates/.changes.j2 b/.github/templates/.changes.j2 deleted file mode 100644 index 076ac09..0000000 --- a/.github/templates/.changes.j2 +++ /dev/null @@ -1,16 +0,0 @@ -{%- set commit_type_heading_mapping = ( - ("breaking", "Breaking Changes"), - ("feature", "Features"), - ("fix", "Bug Fixes"), - ("performance", "Performance improvements"), - ("refactor", "Code Refactoring"), - ("test", "Testing"), - ("documentation", "Documentation"), -) -%} - -{% for commit_type, heading in commit_type_heading_mapping if commit_type in release["elements"] %} -### {{ heading }} - -{% for commit in release["elements"][commit_type] -%} -- {% if commit.scope %}**{{ commit.scope }}:** {% endif %}{{ commit.descriptions[0] }} ([`{{ commit.short_hash }}`]({{ commit.hexsha|commit_hash_url }})) -{% endfor %}{% endfor %} diff --git a/.github/templates/.components/changelog_header.md.j2 b/.github/templates/.components/changelog_header.md.j2 new file mode 100644 index 0000000..15e41e8 --- /dev/null +++ b/.github/templates/.components/changelog_header.md.j2 @@ -0,0 +1,20 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/changelog_header.md.j2 + +#} +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). See +[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines. +{% if ctx.changelog_mode == "update" +%}{# # IMPORTANT: add insertion flag for next version update +#}{{ + insertion_flag ~ "\n" + +}}{% endif +%} diff --git a/.github/templates/.components/changelog_init.md.j2 b/.github/templates/.components/changelog_init.md.j2 new file mode 100644 index 0000000..13ffc99 --- /dev/null +++ b/.github/templates/.components/changelog_init.md.j2 @@ -0,0 +1,34 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/changelog_init.md.j2 + +#}{# +This changelog template initializes a full changelog for the project, +it follows the following logic: + 1. Header + 2. Any Unreleased Details (uncommon) + 3. all previous releases except the very first release + 4. the first release + +#}{# + # Header +#}{% include "changelog_header.md.j2" +%}{# + # Any Unreleased Details (uncommon) +#}{% include "unreleased_changes.md.j2" +%}{# + # Since this is initialization, we are generating all the previous + # release notes per version. The very first release notes is specialized +#}{% if releases | length > 0 +%}{% for release in releases +%}{% if loop.last and ctx.mask_initial_release +%}{%- include "first_release.md.j2" +-%}{% else +%}{%- include "versioned_changes.md.j2" +-%}{% endif +%}{{ "\n" +}}{% endfor +%}{% endif +%} diff --git a/.github/templates/.components/changelog_update.md.j2 b/.github/templates/.components/changelog_update.md.j2 new file mode 100644 index 0000000..8d3a5c6 --- /dev/null +++ b/.github/templates/.components/changelog_update.md.j2 @@ -0,0 +1,72 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/changelog_update.md.j2 + +#}{# +This Update changelog template uses the following logic: + + 1. Read previous changelog file (ex. project_root/CHANGELOG.md) + 2. Split on insertion flag (ex. ) + 3. Print top half of previous changelog + 3. New Changes (unreleased commits & newly released) + 4. Print bottom half of previous changelog + + Note: if a previous file was not found, it does not write anything at the bottom + but render does NOT fail + +#}{% set prev_changelog_contents = prev_changelog_file | read_file | safe +%}{% set changelog_parts = prev_changelog_contents.split(insertion_flag, maxsplit=1) +%}{# +#}{% if changelog_parts | length < 2 +%}{# # insertion flag was not found, check if the file was empty or did not exist +#}{% if prev_changelog_contents | length > 0 +%}{# # File has content but no insertion flag, therefore, file will not be updated +#}{{ changelog_parts[0] +}}{% else +%}{# # File was empty or did not exist, therefore, it will be created from scratch +#}{% include "changelog_init.md.j2" +%}{% endif +%}{% else +%}{# + # Previous Changelog Header + # - Depending if there is header content, then it will separate the insertion flag + # with a newline from header content, otherwise it will just print the insertion flag +#}{% set prev_changelog_top = changelog_parts[0] | trim +%}{% if prev_changelog_top | length > 0 +%}{{ + "%s\n\n%s\n" | format(prev_changelog_top, insertion_flag | trim) + +}}{% else +%}{{ + "%s\n" | format(insertion_flag | trim) + +}}{% endif +%}{% if releases | length > 0 +%}{# # Latest Release Details +#}{% set release = releases[0] +%}{# +#}{% if releases | length == 1 and ctx.mask_initial_release +%}{# # First Release detected +#}{{ "\n" +}}{%- include "first_release.md.j2" +-%}{{ "\n" +}}{# +#}{% elif "# " ~ release.version.as_semver_tag() ~ " " not in changelog_parts[1] +%}{# # The release version is not already in the changelog so we add it +#}{{ "\n" +}}{%- include "versioned_changes.md.j2" +-%}{# +#}{% endif +%}{% endif +%}{# + # Previous Changelog Footer + # - skips printing footer if empty, which happens when the insertion_flag + # was at the end of the file (ignoring whitespace) +#}{% set previous_changelog_bottom = changelog_parts[1] | trim +%}{% if previous_changelog_bottom | length > 0 +%}{{ "\n%s\n" | format(previous_changelog_bottom) +}}{% endif +%}{% endif +%} diff --git a/.github/templates/.components/changes.md.j2 b/.github/templates/.components/changes.md.j2 new file mode 100644 index 0000000..e48f739 --- /dev/null +++ b/.github/templates/.components/changes.md.j2 @@ -0,0 +1,93 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/changes.md.j2 + +#}{% from 'macros.md.j2' import apply_alphabetical_ordering_by_brk_descriptions +%}{% from 'macros.md.j2' import apply_alphabetical_ordering_by_descriptions +%}{% from 'macros.md.j2' import format_breaking_changes_description, format_commit_summary_line +%}{% from 'custom.md.j2' import section_heading_order +%}{# +EXAMPLE: + +### Features + +- Add new feature ([#10](https://domain.com/namespace/repo/pull/10), + [`abcdef0`](https://domain.com/namespace/repo/commit/HASH)) + +- **scope**: Add new feature ([`abcdef0`](https://domain.com/namespace/repo/commit/HASH)) + +### Bug Fixes + +- Fix bug ([#11](https://domain.com/namespace/repo/pull/11), + [`abcdef1`](https://domain.com/namespace/repo/commit/HASH)) + +### BREAKING CHANGES + +- With the change _____, the change causes ___ effect. Ultimately, this section + it is a more detailed description of the breaking change. With an optional + scope prefix like the commit messages above. + +- **scope**: this breaking change has a scope to identify the part of the code that + this breaking change applies to for better context. + +#}{% set max_line_width = max_line_width | default(120) +%}{% set hanging_indent = hanging_indent | default(2) +%}{# +#}{% for type_ in section_heading_order if type_ in commit_objects +%}{# PREPROCESS COMMITS (order by description & format description line) +#}{% set ns = namespace(commits=commit_objects[type_]) +%}{{ apply_alphabetical_ordering_by_descriptions(ns) | default("", true) +}}{# +#}{% set commit_descriptions = [] +%}{# +#}{% for commit in ns.commits +%}{# # Add reference links to the commit summary line +#}{% set description = "- %s" | format(format_commit_summary_line(commit)) +%}{% set description = description | autofit_text_width(max_line_width, hanging_indent) +%}{{ commit_descriptions.append(description) | default("", true) +}}{% endfor +%}{# + # # PRINT SECTION (header & commits) +#}{{ "\n" +}}{{ "### %s\n" | format(type_ | title) +}}{{ "\n" +}}{{ "%s\n" | format(commit_descriptions | unique | join("\n")) +}}{% endfor +-%} +{# + # # Determine if any commits have a breaking change + # # commit_objects is a dictionary of strings to a list of commits { "Features", [ParsedCommit(), ...] } +#}{% set breaking_commits = [] +%}{% for commits in commit_objects.values() +%}{# # Filter out breaking change commits that have no breaking descriptions +#}{{ breaking_commits.extend( + commits | rejectattr("error", "defined") | selectattr("breaking_descriptions.0") + ) | default("", true) +}}{% endfor +%}{# +#}{% if breaking_commits | length > 0 +%}{# PREPROCESS COMMITS +#}{% set brk_ns = namespace(commits=breaking_commits) +%}{{ apply_alphabetical_ordering_by_brk_descriptions(brk_ns) | default("", true) +}}{# +#}{% set brking_descriptions = [] +%}{# +#}{% for commit in brk_ns.commits +%}{% set full_description = "- %s" | format( + format_breaking_changes_description(commit).split("\n\n") | join("\n\n- ") + ) +%}{{ brking_descriptions.append( + full_description | autofit_text_width(max_line_width, hanging_indent) + ) | default("", true) +}}{% endfor +%}{# + # # PRINT BREAKING CHANGE DESCRIPTIONS (header & descriptions) +#}{{ "\n" +}}{{ "### BREAKING CHANGES\n" +}}{{ + "\n%s\n" | format(brking_descriptions | unique | join("\n\n")) +}}{# +#}{% endif +-%} diff --git a/.github/templates/.components/custom.md.j2 b/.github/templates/.components/custom.md.j2 new file mode 100644 index 0000000..36036b7 --- /dev/null +++ b/.github/templates/.components/custom.md.j2 @@ -0,0 +1,15 @@ +{# Ref: https://github.com/python-semantic-release/python-semantic-release/issues/1122#issuecomment-2542518505 + +The types in the section header order corresponds to the ones defined in +PSR's angular commit parser: +https://github.com/python-semantic-release/python-semantic-release/blob/7b3f71697ccfbaef884e1e754b6364e974b134cf/src/semantic_release/commit_parser/angular.py#L46 + +#} +{% set section_heading_order = [ + "features", + "bug fixes", + "performance improvements", + "refactoring", + "testing", + "documentation", +] %} diff --git a/.github/templates/.components/macros.md.j2 b/.github/templates/.components/macros.md.j2 new file mode 100644 index 0000000..27daa84 --- /dev/null +++ b/.github/templates/.components/macros.md.j2 @@ -0,0 +1,170 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/macros.md.j2 + +#}{# + MACRO: format a inline link reference in Markdown +#}{% macro format_link(link, label) +%}{{ "[%s](%s)" | format(label, link) +}}{% endmacro +%} + + +{# + MACRO: commit message links or PR/MR links of commit +#}{% macro commit_msg_links(commit) +%}{% if commit.error is undefined +%}{% set commit_hash_link = format_link( + commit.hexsha | commit_hash_url, + "`%s`" | format(commit.short_hash) + ) +%}{# +#}{% set summary_line = commit.descriptions[0] | safe +%}{% set summary_line = [ + summary_line.split(" ", maxsplit=1)[0] | capitalize, + summary_line.split(" ", maxsplit=1)[1] + ] | join(" ") +%}{# +#}{% if commit.linked_merge_request != "" +%}{# # Add PR references with a link to the PR +#}{% set pr_num = commit.linked_merge_request +%}{% set pr_link = format_link(pr_num | pull_request_url, pr_num) +%}{# + # breaking change v10, remove summary line replacers as PSR will do it for us +#}{% set summary_line = summary_line | replace("(pull request", "(") | replace("(" ~ pr_num ~ ")", "") | trim +%}{% set summary_line = "%s (%s, %s)" | format( + summary_line, + pr_link, + commit_hash_link, + ) +%}{# + # DEFAULT: No PR identifier found, so just append commit hash as url to the commit summary_line +#}{% else +%}{% set summary_line = "%s (%s)" | format(summary_line, commit_hash_link) +%}{% endif +%}{# + # Return the modified summary_line +#}{{ summary_line +}}{% endif +%}{% endmacro +%} + + +{# + MACRO: format commit summary line +#}{% macro format_commit_summary_line(commit) +%}{# # Check for Parsing Error +#}{% if commit.error is undefined +%}{# + # # Add any message links to the commit summary line +#}{% set summary_line = commit_msg_links(commit) +%}{# +#}{% if commit.scope +%}{% set summary_line = "**%s**: %s" | format(commit.scope, summary_line) +%}{% endif +%}{# + # # Return the modified summary_line +#}{{ summary_line +}}{# +#}{% else +%}{# # Return the first line of the commit if there was a Parsing Error +#}{{ (commit.commit.message | string).split("\n", maxsplit=1)[0] +}}{% endif +%}{% endmacro +%} + + +{# + MACRO: format the breaking changes description by: + - Capitalizing the description + - Adding an optional scope prefix +#}{% macro format_breaking_changes_description(commit) +%}{% set ns = namespace(full_description="") +%}{# +#}{% if commit.error is undefined +%}{% for paragraph in commit.breaking_descriptions +%}{% if paragraph | trim | length > 0 +%}{# +#}{% set paragraph_text = [ + paragraph.split(" ", maxsplit=1)[0] | capitalize, + paragraph.split(" ", maxsplit=1)[1] + ] | join(" ") | trim | safe +%}{# +#}{% set ns.full_description = [ + ns.full_description, + paragraph_text + ] | join("\n\n") +%}{# +#}{% endif +%}{% endfor +%}{# +#}{% set ns.full_description = ns.full_description | trim +%}{# +#}{% if commit.scope +%}{% set ns.full_description = "**%s**: %s" | format( + commit.scope, ns.full_description + ) +%}{% endif +%}{% endif +%}{# +#}{{ ns.full_description +}}{% endmacro +%} + + +{# + MACRO: apply smart ordering of commits objects based on alphabetized summaries and then scopes + - Commits are sorted based on the commit type and the commit message + - Commits are grouped by the commit type + - parameter: ns (namespace) object with a commits list + - returns None but modifies the ns.commits list in place +#}{% macro apply_alphabetical_ordering_by_descriptions(ns) +%}{% set ordered_commits = [] +%}{# + # # Eliminate any ParseError commits from input set +#}{% set filtered_commits = ns.commits | rejectattr("error", "defined") | list +%}{# + # # grab all commits with no scope and sort alphabetically by the first line of the commit message +#}{% for commit in filtered_commits | rejectattr("scope") | sort(attribute='descriptions.0') +%}{{ ordered_commits.append(commit) | default("", true) +}}{% endfor +%}{# + # # grab all commits with a scope and sort alphabetically by the scope and then the first line of the commit message +#}{% for commit in filtered_commits | selectattr("scope") | sort(attribute='scope,descriptions.0') +%}{{ ordered_commits.append(commit) | default("", true) +}}{% endfor +%}{# + # # Return the ordered commits +#}{% set ns.commits = ordered_commits +%}{% endmacro +%} + + +{# + MACRO: apply smart ordering of commits objects based on alphabetized breaking changes and then scopes + - Commits are sorted based on the commit type and the commit message + - Commits are grouped by the commit type + - parameter: ns (namespace) object with a commits list + - returns None but modifies the ns.commits list in place +#}{% macro apply_alphabetical_ordering_by_brk_descriptions(ns) +%}{% set ordered_commits = [] +%}{# + # # Eliminate any ParseError commits from input set +#}{% set filtered_commits = ns.commits | rejectattr("error", "defined") | list +%}{# + # # grab all commits with no scope and sort alphabetically by the first line of the commit message +#}{% for commit in filtered_commits | rejectattr("scope") | sort(attribute='breaking_descriptions.0') +%}{{ ordered_commits.append(commit) | default("", true) +}}{% endfor +%}{# + # # grab all commits with a scope and sort alphabetically by the scope and then the first line of the commit message +#}{% for commit in filtered_commits | selectattr("scope") | sort(attribute='scope,breaking_descriptions.0') +%}{{ ordered_commits.append(commit) | default("", true) +}}{% endfor +%}{# + # # Return the ordered commits +#}{% set ns.commits = ordered_commits +%}{% endmacro +%} diff --git a/.github/templates/.components/release_notes_footer.md.j2 b/.github/templates/.components/release_notes_footer.md.j2 new file mode 100644 index 0000000..6d78efa --- /dev/null +++ b/.github/templates/.components/release_notes_footer.md.j2 @@ -0,0 +1,12 @@ +## Installation + +You can install this version via pip from [PyPI](https://pypi.org/project/{{ repo_name }}/{{ version }}/): + +```console +python -m pip install {{ repo_name }}=={{ version }} +``` +or pull the Docker image from [GHCR](https://github.com/{{ repo_owner }}/{{ repo_name }}/pkgs/container/{{ repo_name }}): + +```console +docker pull ghcr.io/{{ repo_owner }}/{{ repo_name }}:{{ version }} +``` diff --git a/.github/templates/.components/unreleased_changes.md.j2 b/.github/templates/.components/unreleased_changes.md.j2 new file mode 100644 index 0000000..9e3f220 --- /dev/null +++ b/.github/templates/.components/unreleased_changes.md.j2 @@ -0,0 +1,18 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/unreleased_changes.md.j2 + +#}{# + +We just display a comparison url from the last release to the main branch, e.g. + +## [Unreleased](https://github.com/afuetterer/python-re3data/compare/0.10.0...main) + +#}{% set version_tag = releases[0].version.as_tag() +%}{% set version_comparison_url = version_tag | compare_url("main") +-%} +## [Unreleased]({{ version_comparison_url }}) +{{ "\n" +}} diff --git a/.github/templates/.components/versioned_changes.md.j2 b/.github/templates/.components/versioned_changes.md.j2 new file mode 100644 index 0000000..a8311a1 --- /dev/null +++ b/.github/templates/.components/versioned_changes.md.j2 @@ -0,0 +1,27 @@ +{# + +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.components/versioned_changes.md.j2 + +#}{# +## vX.X.X (YYYY-MMM-DD) + +#}{% set curr_release_index = releases.index(release) +%}{% set prev_release_index = curr_release_index + 1 +%}{% if 'compare_url' is filter and prev_release_index < releases | length +%}{% set prev_version_tag = releases[prev_release_index].version.as_tag() +%}{% set new_version_tag = release.version.as_tag() +%}{% set version_comparison_url = prev_version_tag | compare_url(new_version_tag) +%}{% endif +-%} +{{ + "## [%s](%s) (%s)" | format( + release.version.as_tag(), + version_comparison_url, + release.tagged_date.strftime("%Y-%m-%d"), + ) +}}{% set commit_objects = release["elements"] +%} +{% include "changes.md.j2" +-%} diff --git a/.github/templates/.release_notes.md.j2 b/.github/templates/.release_notes.md.j2 index 5cfedfa..101729d 100644 --- a/.github/templates/.release_notes.md.j2 +++ b/.github/templates/.release_notes.md.j2 @@ -1,19 +1,64 @@ -{%- set releases = context.history.released.items() | list -%} -{%- set prev_version = releases[1][0] -%} -## Release Notes -{% include ".changes.j2" %} -{{ "**Full Changelog**: (%s)" | format(prev_version | compare_url(version)) }} +{# -## Installation +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/.release_notes.md.j2 -You can install this version via pip from [PyPI](https://pypi.org/project/python-re3data/{{ version }}/): +#}{# EXAMPLE: -```console -python -m pip install python-re3data=={{ version }} -``` +### Features -or pull the Docker image from [GHCR](https://github.com/afuetterer/python-re3data/pkgs/container/python-re3data): +- Add new feature ([#10](https://domain.com/namespace/repo/pull/10), + [`abcdef0`](https://domain.com/namespace/repo/commit/HASH)) -```console -docker pull ghcr.io/afuetterer/python-re3data:{{ version }} -``` +- **scope**: Add new feature + ([`abcdef0`](https://domain.com/namespace/repo/commit/HASH)) + +### Bug Fixes + +- Fix bug (#11, [`abcdef1`](https://domain.com/namespace/repo/commit/HASH)) + +### BREAKING CHANGES + +- With the change _____, the change causes ___ effect. Ultimately, this section + it is a more detailed description of the breaking change. With an optional + scope prefix like the commit messages above. + +- **scope**: this breaking change has a scope to identify the part of the code that + this breaking change applies to for better context. + +--- + +**Detailed Changes**: [vX.X.X...vX.X.X](https://domain.com/namespace/repo/compare/vX.X.X...vX.X.X) + +#}{# # Set line width to 1000 to avoid wrapping as GitHub will handle it +#}{% set max_line_width = max_line_width | default(1000) +%}{% set hanging_indent = hanging_indent | default(2) +%}{% set releases = context.history.released.values() | list +%}{% set curr_release_index = releases.index(release) +%}{% set prev_release_index = curr_release_index + 1 +%}{# +#}{% if 'compare_url' is filter and prev_release_index < releases | length +%}{% set prev_version_tag = releases[prev_release_index].version.as_tag() +%}{% set new_version_tag = release.version.as_tag() +%}{% set version_compare_url = prev_version_tag | compare_url(new_version_tag) +%}{% set detailed_changes_link = '[`{}...{}`]({})'.format( + prev_version_tag, new_version_tag, version_compare_url + ) +%}{% endif +%}{# +#}{% if releases | length == 1 and mask_initial_release +%}{# # On a first release, generate our special message +#}{% include ".components/first_release.md.j2" +%}{% else +%}{# # Not the first release so generate notes normally +#}{% include ".components/versioned_changes.md.j2" +-%}{# +#}{% if detailed_changes_link is defined +%}{{ "\n" +}}{{ "**Full Changelog**: (%s)" | format(detailed_changes_link) +}}{{ "\n\n" +}}{% endif +%}{% endif +%}{% include ".components/release_notes_footer.md.j2" +-%} diff --git a/.github/templates/CHANGELOG.md.j2 b/.github/templates/CHANGELOG.md.j2 index b7c967e..34e9a8f 100644 --- a/.github/templates/CHANGELOG.md.j2 +++ b/.github/templates/CHANGELOG.md.j2 @@ -1,21 +1,28 @@ -# Changelog +{# -All notable changes to this project will be documented in this file. +This template is adapted from: +"python-semantic-release" (MIT License) +https://github.com/python-semantic-release/python-semantic-release/blob/v9.17.0/src/semantic_release/data/templates/angular/md/CHANGELOG.md.j2 -This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). See -[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines. +#}{# + This changelog template controls which changelog creation occurs + based on which mode is provided. -{# UNRELEASED -#} -{% set last_release = context.history.released.items() | first | first -%} -## {{ "[Unreleased](%s)" | format(last_release.as_tag() | compare_url("main")) }} + Modes: + - init: Initialize a full changelog from scratch + - update: Insert new version details where the placeholder exists in the current changelog -{# RELEASED -#} -{% for version, release in context.history.released.items() -%} -{%- if loop.nextitem -%} -{%- set compare_url_ = loop.nextitem[0] | compare_url(version) -%} -## [{{ version.as_tag() }}]({{ compare_url_ }}) ({{ release.tagged_date.strftime("%Y-%m-%d") }}) -{% else -%} -## {{ version.as_tag() }} ({{ release.tagged_date.strftime("%Y-%m-%d") }}) -{% endif -%} -{% include ".changes.j2" %} -{%- endfor -%} +#}{% set insertion_flag = ctx.changelog_insertion_flag +%}{% set this_file = "CHANGELOG.md" +%}{% set unreleased_commits = ctx.history.unreleased | dictsort +%}{% set releases = ctx.history.released.values() | list +%}{# +#}{% if ctx.changelog_mode == "init" +%}{% include ".components/changelog_init.md.j2" +%}{# +#}{% elif ctx.changelog_mode == "update" +%}{% set prev_changelog_file = this_file +%}{% include ".components/changelog_update.md.j2" +%}{# +#}{% endif +-%} diff --git a/CHANGELOG.md b/CHANGELOG.md index f86d73a..b8c2179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,62 +7,170 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased](https://github.com/afuetterer/python-re3data/compare/0.10.0...main) + + ## [0.10.0](https://github.com/afuetterer/python-re3data/compare/0.9.0...0.10.0) (2024-12-11) +### Features + +- Add return_type csv ([#182](https://github.com/afuetterer/python-re3data/pull/182), + [`4123823`](https://github.com/afuetterer/python-re3data/commit/4123823353be1fe9fc018328dd0c0542afc80ab3)) + ### Documentation -- update uv installation instructions (#227) ([`d83fe84`](https://github.com/afuetterer/python-re3data/commit/d83fe8488568ab2632ecde299da9447d680d2bee)) +- Update uv installation instructions ([#227](https://github.com/afuetterer/python-re3data/pull/227), + [`d83fe84`](https://github.com/afuetterer/python-re3data/commit/d83fe8488568ab2632ecde299da9447d680d2bee)) ## [0.9.0](https://github.com/afuetterer/python-re3data/compare/0.8.0...0.9.0) (2024-07-06) +### Features + +- **cli**: Add --outfile option for saving results to disk + ([#166](https://github.com/afuetterer/python-re3data/pull/166), + [`1e689e8`](https://github.com/afuetterer/python-re3data/commit/1e689e850b6f5c117887eb1938b1a336422e5418)) +- **client**: Add repository counting ([#158](https://github.com/afuetterer/python-re3data/pull/158), + [`c1cba53`](https://github.com/afuetterer/python-re3data/commit/c1cba53a408505c673de2aa8b4f6caddcb91cadd)) + ### Documentation -- **readme:** update key features in readme (#165) ([`2396cf5`](https://github.com/afuetterer/python-re3data/commit/2396cf59b1f2d62e917e9b335d8596aa4d3b38d6)) -- add features page (#157) ([`2348b01`](https://github.com/afuetterer/python-re3data/commit/2348b013ad16cacd8a85b72d9f6d488df1ab7f7e)) +- Add features page ([#157](https://github.com/afuetterer/python-re3data/pull/157), + [`2348b01`](https://github.com/afuetterer/python-re3data/commit/2348b013ad16cacd8a85b72d9f6d488df1ab7f7e)) +- **readme**: Update key features in readme ([#165](https://github.com/afuetterer/python-re3data/pull/165), + [`2396cf5`](https://github.com/afuetterer/python-re3data/commit/2396cf59b1f2d62e917e9b335d8596aa4d3b38d6)) ## [0.8.0](https://github.com/afuetterer/python-re3data/compare/0.7.0...0.8.0) (2024-07-03) +### Features + +- Add return_type dict ([#153](https://github.com/afuetterer/python-re3data/pull/153), + [`5894329`](https://github.com/afuetterer/python-re3data/commit/5894329ed52fb014ca4d08a0941e71a66146d446)) +- Add return_type json ([#156](https://github.com/afuetterer/python-re3data/pull/156), + [`f948d6b`](https://github.com/afuetterer/python-re3data/commit/f948d6bef533314327394dbaa250a8518af6b248)) + ## [0.7.0](https://github.com/afuetterer/python-re3data/compare/0.6.0...0.7.0) (2024-07-03) +### Features + +- Add repository filtering based on query string ([#152](https://github.com/afuetterer/python-re3data/pull/152), + [`713d4d1`](https://github.com/afuetterer/python-re3data/commit/713d4d1cd581426a95fd8d6a84f5fa4f4fff1564)) + ## [0.6.0](https://github.com/afuetterer/python-re3data/compare/0.5.0...0.6.0) (2024-07-02) +### Features + +- Add async client ([#139](https://github.com/afuetterer/python-re3data/pull/139), + [`b0c4a48`](https://github.com/afuetterer/python-re3data/commit/b0c4a48b03bc42bec194f4b6c8aa4f1f54d75231)) + ### Documentation -- add installation guide (#129) ([`0de3b5e`](https://github.com/afuetterer/python-re3data/commit/0de3b5e2f93bf162f3c94b1b3eb18cf522962725)) -- enable permalinks for headings (#132) ([`89d0a3d`](https://github.com/afuetterer/python-re3data/commit/89d0a3d2434db5eab1323843a25d6fcb1f903703)) +- Add installation guide ([#129](https://github.com/afuetterer/python-re3data/pull/129), + [`0de3b5e`](https://github.com/afuetterer/python-re3data/commit/0de3b5e2f93bf162f3c94b1b3eb18cf522962725)) +- Enable permalinks for headings ([#132](https://github.com/afuetterer/python-re3data/pull/132), + [`89d0a3d`](https://github.com/afuetterer/python-re3data/commit/89d0a3d2434db5eab1323843a25d6fcb1f903703)) ## [0.5.0](https://github.com/afuetterer/python-re3data/compare/0.4.0...0.5.0) (2024-06-05) +### Breaking Changes + +- Set up resources ([#109](https://github.com/afuetterer/python-re3data/pull/109), + [`0d766d2`](https://github.com/afuetterer/python-re3data/commit/0d766d24f46d6ec9182ac89a743ed5fa88b6a274)) + +### Features + +- Add cli parameters for return_type selection ([#113](https://github.com/afuetterer/python-re3data/pull/113), + [`15668bc`](https://github.com/afuetterer/python-re3data/commit/15668bc833cc147b4c30fc0a096526ef0be8cb46)) +- Set up custom exceptions ([#108](https://github.com/afuetterer/python-re3data/pull/108), + [`a2fa099`](https://github.com/afuetterer/python-re3data/commit/a2fa099f41114ed50f8a9a64a7530cbe23d65a79)) +- **cli**: Add print_error function to highlight errors in console + ([#123](https://github.com/afuetterer/python-re3data/pull/123), + [`f242b10`](https://github.com/afuetterer/python-re3data/commit/f242b1050ab4d6c8b34874e10e170463a59cab10)) + +### Refactoring + +- Add is_eager argument to version_callback ([#106](https://github.com/afuetterer/python-re3data/pull/106), + [`eab6579`](https://github.com/afuetterer/python-re3data/commit/eab6579d3205e98b0bba4a70e3666008ade60795)) +- **cli**: Use rich.console instead of rich.print ([#122](https://github.com/afuetterer/python-re3data/pull/122), + [`a4efea0`](https://github.com/afuetterer/python-re3data/commit/a4efea0d222779642e440a6b486f17235856e721)) + +### Testing + +- Add respx mock route for /repository{id} endpoint ([#114](https://github.com/afuetterer/python-re3data/pull/114), + [`070bbf6`](https://github.com/afuetterer/python-re3data/commit/070bbf67f219a5deb04b3fbaf41ac0845553c76e)) + ## [0.4.0](https://github.com/afuetterer/python-re3data/compare/0.3.0...0.4.0) (2024-05-28) +### Features + +- Set up dockerfile ([#87](https://github.com/afuetterer/python-re3data/pull/87), + [`75d85b5`](https://github.com/afuetterer/python-re3data/commit/75d85b5ef08b6ffbda6baddd87da005d1f0481d7)) + +### Refactoring + +- **client**: Move guard clause to top of _request method ([#78](https://github.com/afuetterer/python-re3data/pull/78), + [`f3eef8b`](https://github.com/afuetterer/python-re3data/commit/f3eef8b7b4316c45a56481e68e1683855c116e35)) + ### Documentation -- add extra css for prompt (#85) ([`16545d7`](https://github.com/afuetterer/python-re3data/commit/16545d74fc7a308a2cb9144465a50b771fabb5a5)) -- add outdated message (#84) ([`7218b47`](https://github.com/afuetterer/python-re3data/commit/7218b47a027d2cc6b043417a59dca7ee458b0fa2)) -- add reference level in navigation (#80) ([`6a41547`](https://github.com/afuetterer/python-re3data/commit/6a415478032210e960d6f7ec7a8c8e840ffb84cf)) +- Add extra css for prompt ([#85](https://github.com/afuetterer/python-re3data/pull/85), + [`16545d7`](https://github.com/afuetterer/python-re3data/commit/16545d74fc7a308a2cb9144465a50b771fabb5a5)) +- Add outdated message ([#84](https://github.com/afuetterer/python-re3data/pull/84), + [`7218b47`](https://github.com/afuetterer/python-re3data/commit/7218b47a027d2cc6b043417a59dca7ee458b0fa2)) +- Add reference level in navigation ([#80](https://github.com/afuetterer/python-re3data/pull/80), + [`6a41547`](https://github.com/afuetterer/python-re3data/commit/6a415478032210e960d6f7ec7a8c8e840ffb84cf)) ## [0.3.0](https://github.com/afuetterer/python-re3data/compare/0.2.0...0.3.0) (2024-05-26) +### Features + +- **cli**: Set up repository list and get commands ([#76](https://github.com/afuetterer/python-re3data/pull/76), + [`44987e6`](https://github.com/afuetterer/python-re3data/commit/44987e6ba20f51181dbea2c2d3794a3a96ddf6a5)) + +### Testing + +- Add respx mock route for /repositories endpoint ([#75](https://github.com/afuetterer/python-re3data/pull/75), + [`59f7d58`](https://github.com/afuetterer/python-re3data/commit/59f7d58e65d91575c571e6bbea51957900424fdc)) +- Set up zenodo_id fixture for re-use ([#72](https://github.com/afuetterer/python-re3data/pull/72), + [`e926c07`](https://github.com/afuetterer/python-re3data/commit/e926c07419f2720d7d3f9c97f01285e52a52863e)) + ### Documentation -- add doi to citation.cff and badge to readme (#66) ([`2fde7ee`](https://github.com/afuetterer/python-re3data/commit/2fde7ee3e2afa7c1dbbd44bf26c8e918d6e79396)) +- Add doi to citation.cff and badge to readme ([#66](https://github.com/afuetterer/python-re3data/pull/66), + [`2fde7ee`](https://github.com/afuetterer/python-re3data/commit/2fde7ee3e2afa7c1dbbd44bf26c8e918d6e79396)) ## [0.2.0](https://github.com/afuetterer/python-re3data/compare/0.1.0...0.2.0) (2024-05-23) +### Features + +- Set up client ([#64](https://github.com/afuetterer/python-re3data/pull/64), + [`62300bc`](https://github.com/afuetterer/python-re3data/commit/62300bcf2fa2dd7f1a4c8bbaf7b7ae6bab4e9e77)) + ### Documentation -- **readme:** remove table of contents (#62) ([`8f224e8`](https://github.com/afuetterer/python-re3data/commit/8f224e8ec1819a2cbf74738af7b4e84d34d663bf)) -- **readme:** add status badge (#56) ([`cfc9f5a`](https://github.com/afuetterer/python-re3data/commit/cfc9f5a5d2b993690c5d4507603ca5bb7dac0f5e)) -- add api reference (#47) ([`9e455c4`](https://github.com/afuetterer/python-re3data/commit/9e455c490183109ca3fb7026e554ca53c7bcad12)) -- add changelog to docs (#43) ([`a167c46`](https://github.com/afuetterer/python-re3data/commit/a167c46b2b80cbefa2b7a6aee2bc0ccdbb0f6459)) -- **readme:** add pypi badges (#37) ([`f4b31a9`](https://github.com/afuetterer/python-re3data/commit/f4b31a92c2c2cc9db6c7ee484abf3e8ba6a02860)) +- Add api reference ([#47](https://github.com/afuetterer/python-re3data/pull/47), + [`9e455c4`](https://github.com/afuetterer/python-re3data/commit/9e455c490183109ca3fb7026e554ca53c7bcad12)) +- Add changelog to docs ([#43](https://github.com/afuetterer/python-re3data/pull/43), + [`a167c46`](https://github.com/afuetterer/python-re3data/commit/a167c46b2b80cbefa2b7a6aee2bc0ccdbb0f6459)) +- **readme**: Add pypi badges ([#37](https://github.com/afuetterer/python-re3data/pull/37), + [`f4b31a9`](https://github.com/afuetterer/python-re3data/commit/f4b31a92c2c2cc9db6c7ee484abf3e8ba6a02860)) +- **readme**: Add status badge ([#56](https://github.com/afuetterer/python-re3data/pull/56), + [`cfc9f5a`](https://github.com/afuetterer/python-re3data/commit/cfc9f5a5d2b993690c5d4507603ca5bb7dac0f5e)) +- **readme**: Remove table of contents ([#62](https://github.com/afuetterer/python-re3data/pull/62), + [`8f224e8`](https://github.com/afuetterer/python-re3data/commit/8f224e8ec1819a2cbf74738af7b4e84d34d663bf)) ## 0.1.0 (2024-05-20) -### Documentation +### Features -- **readme:** add short project description (#28) ([`c20f23e`](https://github.com/afuetterer/python-re3data/commit/c20f23e7b682c10c0749043e851b81cf0ec80f61)) -- **readme:** add similar projects (#23) ([`7e3e919`](https://github.com/afuetterer/python-re3data/commit/7e3e919d512d9f8556a3c45e7a6f164b9e19be9a)) -- set up python-semantic-release templates (#21) ([`bcd976a`](https://github.com/afuetterer/python-re3data/commit/bcd976aa4dcc25188dcf16f82d2a5cee475c5983)) -- **readme:** add codeql badge (#18) ([`ee6f6aa`](https://github.com/afuetterer/python-re3data/commit/ee6f6aa7dfb1f2b8b6e4d8e10bbe67b10af00c04)) +- Add initial cli ([#32](https://github.com/afuetterer/python-re3data/pull/32), + [`0b5b2c4`](https://github.com/afuetterer/python-re3data/commit/0b5b2c4a855656196d0c502de93752c780be6c40)) + +### Documentation +- Set up python-semantic-release templates ([#21](https://github.com/afuetterer/python-re3data/pull/21), + [`bcd976a`](https://github.com/afuetterer/python-re3data/commit/bcd976aa4dcc25188dcf16f82d2a5cee475c5983)) +- **readme**: Add codeql badge ([#18](https://github.com/afuetterer/python-re3data/pull/18), + [`ee6f6aa`](https://github.com/afuetterer/python-re3data/commit/ee6f6aa7dfb1f2b8b6e4d8e10bbe67b10af00c04)) +- **readme**: Add short project description ([#28](https://github.com/afuetterer/python-re3data/pull/28), + [`c20f23e`](https://github.com/afuetterer/python-re3data/commit/c20f23e7b682c10c0749043e851b81cf0ec80f61)) +- **readme**: Add similar projects ([#23](https://github.com/afuetterer/python-re3data/pull/23), + [`7e3e919`](https://github.com/afuetterer/python-re3data/commit/7e3e919d512d9f8556a3c45e7a6f164b9e19be9a)) diff --git a/pyproject.toml b/pyproject.toml index a112871..8d3bbf6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -304,13 +304,17 @@ tag_format = "{version}" version_variables = [ "src/re3data/__about__.py:__version__", ] -build_command = """ +build_command = ''' sed -i "s/^version: .*/version: $NEW_VERSION/" CITATION.cff sed -i "s/^date-released: .*/date-released: $(date "+%Y-%m-%d")/" CITATION.cff -git add CITATION.cff -""" +sed -i "s|/compare/[0-9]*\.[0-9]*\.[0-9]*...main|/compare/$NEW_VERSION...main|" CHANGELOG.md +git add CHANGELOG.md CITATION.cff +''' +changelog.mode = "update" +changelog.insertion_flag = "" changelog.template_dir = ".github/templates" -changelog.environment.keep_trailing_newline = true +changelog.exclude_commit_patterns = [ "^build", "^chore", "^style", "^ci" ] +changelog.environment.keep_trailing_newline = false [tool.typos] # Ref: https://github.com/crate-ci/typos/blob/master/docs/reference.md # add "spellchecker:disable-line" to ignore specific lines