From 39fa783340f69b79d0923630b8e030606a519a90 Mon Sep 17 00:00:00 2001 From: Heinz-Alexander Fuetterer Date: Sun, 12 Nov 2023 18:29:58 +0100 Subject: [PATCH] build: add semantic-release config --- .github/workflows/main.yml | 20 ++++++ pyproject.toml | 23 +++++-- templates/.changelog.md | 119 +++++++++++++++++++++++++++++++++ templates/.changes.j2 | 16 +++++ templates/.release_notes.md.j2 | 1 + templates/CHANGELOG.md.j2 | 25 +++++++ 6 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 templates/.changelog.md create mode 100644 templates/.changes.j2 create mode 100644 templates/.release_notes.md.j2 create mode 100644 templates/CHANGELOG.md.j2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e9744c9..5c6507d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,3 +20,23 @@ jobs: test: uses: ./.github/workflows/test.yml secrets: inherit + release: + # disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'afuetterer' + runs-on: ubuntu-22.04 + needs: + - lint + - test + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 # get all commits and tags + token: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} + - name: Create semantic release + uses: python-semantic-release/python-semantic-release@d38d71ef2ae2b3c34066557ddb822385c1730c7f # v8.3.0 + with: + # allows for python-semantic-release to push to protected main branch + github_token: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} + git_committer_name: github-actions[bot] + git_committer_email: 41898282+github-actions[bot]@users.noreply.github.com + root_options: -vv --noop diff --git a/pyproject.toml b/pyproject.toml index c474e3c..1a6ff34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,15 +100,13 @@ python -c "import json;print(json.load(open('coverage.json'))['totals']['percent """ [tool.hatch.envs.lint] -features = [ - "lint", -] +features = [ "lint"] [tool.hatch.envs.lint.scripts] style = "SKIP=mypy pre-commit run --all-files --color=always" typing = "pre-commit run --all-files --color=always mypy" all = [ "style", - # "typing", + "typing", ] [tool.hatch.envs.docs] @@ -213,6 +211,23 @@ show_error_context = true using = "PEP631" format = "ansi" +# python-semantic-release +# Ref: https://python-semantic-release.readthedocs.io/en/latest/configuration.html#settings +# ------------------------------------------------------------------------------ + +[tool.semantic_release] +commit_message = "chore: release {version}\n\nAutomatically generated by python-semantic-release [skip ci]" +logging_use_named_masks = true +major_on_zero = false +tag_format = "{version}" +version_variables = [ + "src/oaipmh_scythe/__about__.py:__version__", +] +build_command = """ +python -m pip install build +python -m build +""" + # typos # Ref: https://github.com/crate-ci/typos/blob/master/docs/reference.md # ------------------------------------------------------------------------------ diff --git a/templates/.changelog.md b/templates/.changelog.md new file mode 100644 index 0000000..68137f3 --- /dev/null +++ b/templates/.changelog.md @@ -0,0 +1,119 @@ +## [0.8.0](https://github.com/afuetterer/oaipmh-scythe/compare/0.7.0...0.8.0) (2023-11-16) + +Note: Rename project to oaipmh-scythe when forking it from [mloesch/sickle](https://github.com/mloesch/sickle) to +[afuetterer/oaipmh-scythe](https://github.com/afuetterer/oaipmh-scythe) + +### Breaking Changes + +- drop support for Python 2 +- drop support for EOL Python 3.7 and below +- rename Sickle class to Scythe to reflect the change of the project name +- switch to PEP8 compliant names for methods (ListRecords() -> list_records()) +- remove .next() method from iterator classes + +### Features + +- set up default custom user agent (oaipmh-scythe/{version}) + +### Performance Improvements + +- make iterator classes yield their responses + +### Code Refactoring + +- switch from requests to httpx +- make BaseOAIIterator an ABC +- move version information to __about__.py +- add a custom base exception + +### Testing + +- switch from nose to pytest +- add tests for Python 3.8 - 3.12 in CI +- use canned responses from Zenodo to test harvesting logic (vcr.py) + +### Documentation + +- update license text +- update authors and contributors +- update copyright notice in src files +- add contributor guide +- add security policy +- add issue and pull request templates +- add custom GitHub labels +- switch from Sphinx to mkdocs-material +- switch from Read the Docs to GitHub pages +- switch from reStructuredText to Markdown +- switch to Zenodo for harvesting examples +- update README badges + +### Other + +- switch from Travis CI to Github actions for CI +- add scheduled dependency updates with Dependabot +- add pre-commit hooks (e.g. ruff, mypy) +- switch to src layout +- switch from setup.py to pyproject.toml +- switch to hatch for project setup +- add type annotations +- switch to Google style docstrings +- rename first tags of sickle project for consistency (e.g. v0.5 -> 0.5.0) +- enable CodeQL scanning +- add OpenSSF Scorecard report + +## [0.7.0](https://github.com/afuetterer/oaipmh-scythe/compare/0.6.5...0.7.0) (2020-05-17) + +- method for record metadata extraction has been extracted (`Record.get_metadata()`) to make subclassing easier ([mloesch/sickle#38](https://github.com/mloesch/sickle/pull/38)) +- retryable HTTP status codes and default wait time between retries can be customized ([mloesch/sickle#21](https://github.com/mloesch/sickle/issues/21) [mloesch/sickle#41](https://github.com/mloesch/sickle/pull/41)) +- retry logic has been fixed: `max_retries` parameter now refers to no. of retries, not counting the initial request anymore +- the default number of HTTP retries has been set to 0 (= no retries) +- fix for [mloesch/sickle#39](https://github.com/mloesch/sickle/pull/39) + +## [0.6.5](https://github.com/afuetterer/oaipmh-scythe/compare/0.6.4...0.6.5) (2020-01-12) + +- fix: repr methods where causing an exception on Python 3 ([mloesch/sickle#30](https://github.com/mloesch/sickle/issues/30)) + +## [0.6.4](https://github.com/afuetterer/oaipmh-scythe/compare/0.6.3...0.6.4) (2018-10-02) + +- fix: resumption token with empty body indicates last response ([mloesch/sickle#25](https://github.com/mloesch/sickle/issues/25)) + +## [0.6.3](https://github.com/afuetterer/oaipmh-scythe/compare/0.6.2...0.6.3) (2018-04-08) + +- fix unicode problems (issues 20 & 22) + +## [0.6.2](https://github.com/afuetterer/oaipmh-scythe/compare/0.6.1...0.6.2) (2017-08-11) + +- missing datestamp and identifier elements in record header don\'t break harvesting +- lxml resolve_entities disabled () + +## [0.6.1](https://github.com/afuetterer/oaipmh-scythe/compare/0.5.0...0.6.1) (2016-11-13) + +- it is now possible to pass any keyword arguments to requests +- the encoding used to decode the server response can be overridden + +## [0.5.0](https://github.com/afuetterer/oaipmh-scythe/compare/0.4.0...0.5.0) (2015-11-12) + +- support for Python 3 +- consider resumption tokens with empty tag bodies + +## [0.4.0](https://github.com/afuetterer/oaipmh-scythe/compare/0.3.0...0.4.0) (2015-05-31) + +- bug fix: resumptionToken parameter is exclusive +- added support for harvesting complete OAI-XML responses + +## [0.3.0](https://github.com/afuetterer/oaipmh-scythe/compare/0.2.0...0.3.0) (2013-04-17) + +- added support for protected OAI interfaces (basic authentication) +- made class mapping for OAI elements configurable +- added options for HTTP timeout and max retries +- added handling of HTTP 503 responses + +## 0.2.0 (2013-02-26) + +- OAI items are now represented as their own classes instead of XML elements +- library raises OAI-specific exceptions +- made lxml a required dependency + +## 0.1.0 (2013-02-20) + +First public release. diff --git a/templates/.changes.j2 b/templates/.changes.j2 new file mode 100644 index 0000000..a9bcd6f --- /dev/null +++ b/templates/.changes.j2 @@ -0,0 +1,16 @@ +{%- 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/templates/.release_notes.md.j2 b/templates/.release_notes.md.j2 new file mode 100644 index 0000000..53f4f87 --- /dev/null +++ b/templates/.release_notes.md.j2 @@ -0,0 +1 @@ +{% include ".changes.j2" %} diff --git a/templates/CHANGELOG.md.j2 b/templates/CHANGELOG.md.j2 new file mode 100644 index 0000000..3d30246 --- /dev/null +++ b/templates/CHANGELOG.md.j2 @@ -0,0 +1,25 @@ +# 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. +{% macro version_compare_url(prev_version, version) -%} +https://github.com/{{ context.repo_owner }}/{{ context.repo_name }}/compare/{{ prev_version }}...{{ version }} +{%- endmacro %} + +{# UNRELEASED -#} +{% set last_release = context.history.released.items() | first | first -%} +{% set unreleased = version_compare_url(last_release.as_tag(), "main") -%} +## [Unreleased]({{ unreleased }}) + +{# RELEASED #} +{% for version, release in context.history.released.items() if "unknown" not in release["elements"] or release["elements"]|length > 1 -%} +{% if version.as_tag() > "0.8.0" -%}{# Generate changelog entries for releases > 0.8.0 #} +{%- set prev_version = loop.nextitem[0] -%} +{%- set compare_url = version_compare_url(prev_version, version) -%} +## [{{ version.as_tag() }}]({{ compare_url }}) ({{ release.tagged_date.strftime("%Y-%m-%d") }}) +{% include ".changes.j2" %} +{% endif -%} +{% endfor -%} +{% include ".changelog.md" %}{# insert manually curated changelog of sickle project -#}