From 9814714bc3712200764abeaab8c572a19228536d Mon Sep 17 00:00:00 2001 From: Damian Czajkowski Date: Fri, 13 Mar 2026 12:45:22 +0100 Subject: [PATCH] build: add git-cliff for automated changelog and release notes --- .github/workflows/prepare_release.yml | 19 +++- CHANGELOG.md | 158 +------------------------- cliff.toml | 89 +++++++++++++++ pyproject.toml | 3 + 4 files changed, 116 insertions(+), 153 deletions(-) create mode 100644 cliff.toml diff --git a/.github/workflows/prepare_release.yml b/.github/workflows/prepare_release.yml index 7ab3f28a..8649a189 100644 --- a/.github/workflows/prepare_release.yml +++ b/.github/workflows/prepare_release.yml @@ -3,7 +3,7 @@ name: Prepare release on: push: tags: - - '*' + - "*" workflow_call: workflow_dispatch: @@ -22,7 +22,23 @@ jobs: needs: - build runs-on: ubuntu-latest + permissions: + contents: write steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Generate release notes + id: release-notes + uses: orhun/git-cliff-action@v4 + with: + config: cliff.toml + args: --latest --strip all + env: + OUTPUT: RELEASE_NOTES.md + GITHUB_REPO: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Download all the dists uses: actions/download-artifact@v4 with: @@ -35,6 +51,7 @@ jobs: files: | ./dist/* draft: true + body_path: RELEASE_NOTES.md - name: Summary run: | echo "# Release summary" >> $GITHUB_STEP_SUMMARY diff --git a/CHANGELOG.md b/CHANGELOG.md index 434f1e18..500a2793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,159 +1,13 @@ # CHANGELOG -## 0.15.2 (2025-08-28) +All notable unreleased changes to this project will be documented in this file. -- Changed code typing to satisfy MyPy 1.11.0 version -- Added support for `async_client=false` to work with `enable_custom_operations=true` -- Fix propagating `convert_to_snake_case` to clients during package generation -- Added ClientForwardRefsPlugin to standard plugins. -- Re-added model_rebuild calls for input types with forward references. -- Fixed fragments on interfaces being omitted from generated client. -- Fixed @include directive result type when using convert_to_snake_case option. -- Added Custom query builder feature. +For released versions, see the [Releases](https://github.com/mirumee/ariadne-codegen/releases) page. -## 0.14.0 (2024-07-17) +## Unreleased -- Added `ClientForwardRefsPlugin` to standard plugins. -- Re-added `model_rebuild` calls for input types with forward references. -- Fixed fragments on interfaces being omitted from generated client. -- Fixed `@Include` directive result type when using `convert_to_snake_case` option. -- Added Custom query builder feature. +### โš ๏ธ Breaking Changes +### ๐Ÿ“š Documentation -## 0.13.0 (2024-03-4) - -- Fixed `str_to_snake_case` utility to capture fully capitalized words followed by an underscore. -- Re-added `model_rebuild` calls for models with forward references. -- Fixed potential name conflicts between field args and generated client's method code. - - -## 0.12.0 (2024-02-05) - -- Fixed `graphql-transport-ws` protocol implementation not waiting for the `connection_ack` message on new connection. -- Fixed `get_client_settings` mutating `config_dict` instance. -- Added support to `graphqlschema` for saving schema as a GraphQL file. -- Restored `model_rebuild` calls for top level fragment models. - - -## 0.11.0 (2023-12-05) - -- Removed `model_rebuild` calls for generated input, fragment and result models. -- Added `NoReimportsPlugin` that makes the `__init__.py` of generated client package empty. -- Added `include_all_inputs` config flag to generate only inputs used in supplied operations. -- Added `include_all_enums` config flag to generate only enums used in supplied operations. -- Added `operationName` to payload sent by generated client's methods. -- Fixed base clients to pass `mypy --strict` without installed optional dependencies. -- Renamed `GraphQlClientInvalidResponseError` to `GraphQLClientInvalidResponseError` (breaking change). -- Changed base clients to raise `GraphQLClientGraphQLMultiError` for payloads with `errors` key but no `data` (breaking change). - - -## 0.10.0 (2023-11-15) - -- Fixed generating results for nullable fields with nullable directives. -- Changed `include_comments` option to accept enum value, changed default to `"stable"`, deprecated boolean support. Added `get_file_comment` plugin hook. -- Changed `str_to_snake_case` utility to correctly handle capitalized words. -- Digits in Python names are now preceded by an underscore (breaking change). -- Fixed parsing of unions and interfaces to always add `__typename` to generated result models. -- Added escaping of enum values which are Python keywords by appending `_` to them. -- Fixed `enums_module_name` option not being passed to generators. -- Added additional base clients supporting the Open Telemetry tracing. Added `opentelemetry_client` config option. -- Changed generated client's methods to pass `**kwargs` to base client's `execute` and `execute_ws` methods (breaking change for custom base clients). -- Added `operation_definition` argument to `generate_client_method` plugin hook. -- Added `ExtractOperationsPlugin` that extracts operation strings from client methods to separate module. -- Added Python 3.12 to tested versions. - - -## 0.9.0 (2023-09-11) - -- Fixed generating operation string for nested inline fragments. -- Removed scalars module. Changed generated models and client to use annotated types for custom scalars. Removed `scalars_module_name` option. Removed `generate_scalars_module`, `generate_scalars_cod`, `generate_scalar_annotation` and `generate_scalar_imports` plugin hooks. -- Removed pydantic warnings for fields with `model_` prefix. -- Fixed generating result types with nullable directives. - - -## 0.8.0 (2023-08-22) - -- Added support for `Upload` scalar. Added support for file uploads to `AsyncBaseClient` and `BaseClient`. -- Added validation of defined operations against the schema. -- Removed `mixin` directive from fragment string included in operation string sent to server. -- Added support for `mixin` directive on fragments definitions. -- Added support for fragments defined on subtype of field's type. -- Added default representation for a field name consisting only of underscores. -- Changed generated client and models to use pydantic v2. -- Changed custom scalars implementation to utilize pydantic's `BeforeValidator` and `PlainSerializer`. Added `scalars_module_name` option. Replaced `generate_scalars_parse_dict` and `generate_scalars_serialize_dict` with `generate_scalar_annotation` and `generate_scalar_imports` plugin hooks. -- Unified annotations in generated client to be compatible with python < 3.9. -- Fixed generating default values of input types from remote schemas. -- Changed generating of input and result field names to add `_` to names reserved by pydantic. - - -## 0.7.1 (2023-06-06) - -- Fixed `AsyncBaseClient` and `BaseClient` to send `Content-Type` header with requests. - - -## 0.7.0 (2023-06-01) - -- Added support for subscriptions as async generators. -- Changed how fragments are handled to generate separate module with fragments as mixins. -- Fixed `ResultTypesGenerator` to trigger `generate_result_class` for each result model. -- Changed processing of models fields to trim leading underscores. -- Added `ShorterResultsPlugin` to standard plugins. -- Fixed handling of inline fragments inside other fragments. -- Changed generated unions to use pydantic's discriminated unions feature. -- Replaced HTTPX's `json=` serializer for query payloads with pydantic's `pydantic_encoder`. -- Removed `mixin` directive from operation string sent to server. -- Fixed `ShorterResultsPlugin` that generated faulty code for discriminated unions. -- Changed generator to ignore unused fragments which should be unpacked in queries. -- Changed type hints for parse and serialize methods of scalars to `typing.Any`. -- Added `process_schema` plugin hook. - - -## 0.6.0 (2023-04-18) - -- Changed logic how custom scalar imports are generated. Deprecated `import_` key. -- Added escaping of GraphQL names which are Python keywords by appending `_` to them. -- Fixed parsing of list variables. -- Changed base clients to remove unset arguments and input fields from variables payload. -- Added `process_name` plugin hook. - - -## 0.5.0 (2023-04-05) - -- Added generation of GraphQL schema's Python representation. -- Fixed annotations for lists. -- Fixed support of custom operation types names. -- Unlocked versions of black, isort, autoflake and dev dependencies -- Added `remote_schema_verify_ssl` option. -- Changed how default values for inputs are generated to handle potential cycles. -- Fixed `BaseModel` incorrectly calling `parse` and `serialize` methods on entire list instead of its items for `list[Scalar]`. - - -## 0.4.0 (2023-03-20) - -- Fixed generating models from interfaces with inline fragments. -- Added default `None` values for generated methods optional arguments. -- Added basic plugin system. -- Added `InitFileGenerator`, `EnumsGenerator`, `ClientGenerator` and `ArgumentsGenerator` plugin hooks. -- Added `InputTypesGenerator` and `ResultTypesGenerator` plugin hooks. -- Added `ScalarsDefinitionsGenerator` and `PackageGenerator` plugin hooks. -- Added support for `[tool.ariadne-codegen]` section key. Deprecated `[ariadne-codegen]`. -- Added support for environment variables to remote schema headers values. -- Added `--config` argument to `ariadne-codegen` script, to support reading configuration from custom path. - - -## 0.3.0 (2023-02-21) - -- Changed generated code to pass `mypy --strict`. -- Changed base clients to get full url from user. -- Added support for custom scalars. - - -## 0.2.1 (2023-02-13) - -- Fixed incorrectly raised exception when using custom scalar as query argument type. - - -## 0.2.0 (2023-02-02) - -- Added `remote_schema_url` and `remote_schema_headers` settings to support reading remote schemas. -- Added `headers` argument to `__init__` methods of `BaseClient` and `AsyncBaseClient`. +### ๐Ÿ› ๏ธ Build System diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 00000000..2d5ebe7d --- /dev/null +++ b/cliff.toml @@ -0,0 +1,89 @@ +# GitHub integration is activated in CI via GITHUB_REPO env var (set in prepare_release.yml). +# For local use (just changelog-preview / just release-notes), no token is needed. +# [remote.github] owner/repo can also be set here to enable local GitHub-enriched output +# when GITHUB_TOKEN is available, but it is omitted to keep local commands offline-friendly. + +[changelog] +header = """# CHANGELOG + +All notable unreleased changes to this project will be documented in this file. + +For released versions, see the [Releases](https://github.com/mirumee/ariadne/releases) page. + +""" +# Template produces two zones: +# 1. Summary sections โ€“ grouped, emoji-prefixed, breaking changes first (CHANGELOG.md / release body top) +# 2. What's Changed โ€“ flat list of every commit with contributor @mentions and PR links (release body only) +body = """ +{% if version -%} +## {{ version }} ({{ timestamp | date(format="%Y-%m-%d") }}) +{% else -%} +## Unreleased +{% endif -%} +{% set breaking_commits = commits | filter(attribute="breaking", value=true) -%} +{% if breaking_commits %} +### โš ๏ธ Breaking Changes +{% for commit in breaking_commits -%} +- **{{ commit.message | upper_first | trim }}**{% if commit.body %} + + {{ commit.body | trim | indent(prefix=" ") }} +{% endif %} +{% endfor %} +{%- endif %} +{%- for group, commits in commits | group_by(attribute="group") -%} +{%- set non_breaking = commits | filter(attribute="breaking", value=false) -%} +{%- if non_breaking and group != "_misc" %} +### {{ group }} +{% for commit in non_breaking -%} +- {{ commit.message | upper_first | trim }}{% if commit.remote.username %} (by @{{ commit.remote.username }}{% if commit.remote.pr_number %} in [#{{ commit.remote.pr_number }}](https://github.com/mirumee/ariadne/pull/{{ commit.remote.pr_number }}){% endif %}){% endif %} +{% endfor %} +{%- endif -%} +{% endfor %} +{% if version %} +## What's Changed +{% for commit in commits -%} +* {{ commit.message | upper_first | trim }}{% if commit.remote.username %} by @{{ commit.remote.username }}{% endif %}{% if commit.remote.pr_number %} in [#{{ commit.remote.pr_number }}](https://github.com/mirumee/ariadne/pull/{{ commit.remote.pr_number }}){% endif %} +{% endfor %} +{%- if github.contributors is defined -%} +{%- set new_contributors = github.contributors | filter(attribute="is_first_time", value=true) -%} +{%- if new_contributors | length != 0 %} +### New Contributors +{% for contributor in new_contributors -%} +* @{{ contributor.username }} made their first contribution{% if contributor.pr_number %} in [#{{ contributor.pr_number }}](https://github.com/mirumee/ariadne/pull/{{ contributor.pr_number }}){% endif %} +{% endfor %} +{%- endif -%} +{%- endif %} +**Full Changelog**: https://github.com/mirumee/ariadne/compare/{{ previous.version }}...{{ version }} +{% endif -%} +""" +trim = true +footer = "" + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false +protect_breaking_commits = false +# Keep all conventional commits (including chore/type/style) so they appear in "What's Changed". +# Non-conventional commits (e.g. "Benchmark results for 3.14") are removed by filter_unconventional. +filter_commits = false +sort_commits = "oldest" + +# Only include stable release tags (no .rc, .dev, .b, .beta, .alpha suffixes) +tag_pattern = "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$" +# Skip pre-release tags โ€“ their commits are folded into the next stable release +skip_tags = "\\.(rc|dev)[0-9]*$" +ignore_tags = "\\.(b|beta|alpha)[0-9]*$" + +commit_parsers = [ + { message = "^feat", group = "โœจ New Features" }, + { message = "^fix", group = "๐Ÿ› Bug Fixes" }, + { message = "^perf", group = "โšก Performance" }, + { message = "^refactor", group = "โ™ป๏ธ Refactoring" }, + { message = "^docs?", group = "๐Ÿ“š Documentation" }, + { message = "^build", group = "๐Ÿ› ๏ธ Build System" }, + { message = "^ci", group = "๐Ÿ‘ท CI/CD" }, + { message = "^test", group = "๐Ÿงช Testing" }, + # Grouped as _misc so they appear in "What's Changed" but are hidden from the summary sections + { message = ".*", group = "_misc" }, +] diff --git a/pyproject.toml b/pyproject.toml index aea623b3..8824691a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,9 @@ check = [ "hatch test --cover", "hatch run types:check", ] +changelog-preview = "git cliff --unreleased --strip all" +changelog-update = "git cliff --unreleased -o CHANGELOG.md" +release-notes = "git cliff --latest --strip all" ## Types environment