diff --git a/.github/workflows/bump_main.yaml b/.github/workflows/bump_main.yaml new file mode 100644 index 0000000..d609195 --- /dev/null +++ b/.github/workflows/bump_main.yaml @@ -0,0 +1,63 @@ +name: Bump Release +on: + workflow_dispatch: + inputs: + create_release: + type: boolean + description: 'Create GitHub Release' + required: false + default: false + + + +jobs: + bump-main: + if: "!contains(github.event.commits[0].message, 'chore(release)')" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ssh-key: ${{ secrets.deploy-key }} + + - name: Set up git-cliff + uses: kenji-miyake/setup-git-cliff@v1 + + - name: Run git-cliff version check + run: git cliff --version + - name: Determine next version and generate changelog + id: version + run: | + # Get current version from latest tag + CURRENT_VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0") + echo "Current version: $CURRENT_VERSION" + + # Use git-cliff to calculate next version automatically + BUMPED_VERSION=$(git cliff --config cliff.toml --bumped-version) + NEXT_VERSION="${BUMPED_VERSION}" + echo "Next version: $NEXT_VERSION" + echo "version=$NEXT_VERSION" >> $GITHUB_OUTPUT + + # Generate full changelog with the new version + git cliff --config cliff.toml --tag $NEXT_VERSION --output CHANGELOG.md + + # Generate release notes for this version only + git cliff --config cliff.toml --unreleased --tag $NEXT_VERSION --strip all > GITHUB_CHANGELOG.md + + - name: Commit and tag release + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add CHANGELOG.md + git commit -m "chore(release): prepare for ${{ steps.version.outputs.version }}" || echo "No changes to commit" + git tag -a ${{ steps.version.outputs.version }} -m "Release ${{ steps.version.outputs.version }}" + git push + git push origin tag ${{ steps.version.outputs.version }} + + - name: Upload github release + uses: softprops/action-gh-release@v1 + if: inputs.create_release == true + with: + body_path: GITHUB_CHANGELOG.md + tag_name: ${{ steps.version.outputs.version }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1bc368b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,299 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [unreleased] + +### Features + +- Update readme +- Add license +- Add AMQP test +- Add AMQP support +- Add ci +- Add ci steps +- Update test.yaml +- Add license and version to client properties (#27) + +Add license an version to client properties +- Update test.yaml to use Ubuntu 22.04 +- Update README.md (#68) +- Add the example for super stream (#70) + +* Add the example for super stream +--------- +Signed-off-by: Gabriele Santomaggio +- Added sub_entry_batch example, modified README linking to the example… (#88) + +* added sub_entry_batch example, modified README linking to the example and bumping the version + +* Formatting (#89) + +Signed-off-by: Gabriele Santomaggio + +--------- + +Signed-off-by: Gabriele Santomaggio +Co-authored-by: Gabriele Santomaggio +- Add performances documentation (#91) + +Signed-off-by: Gabriele Santomaggio +- Update documentation [skip ci] (#95) + +* update documentation [skip ci] + +--------- + +Signed-off-by: Gabriele Santomaggio +- Add build and test documentation (#106) + +Signed-off-by: Gabriele Santomaggio +- Add documentation [skip ci] (#116) + +* add documentation [skip ci] + +Signed-off-by: Gabriele Santomaggio +- Update to 0.12.0 (#120) + +Signed-off-by: Gabriele Santomaggio +- Add External configuration (#145) + +* Add external Auth Configuration +--------- + +Signed-off-by: Gabriele Santomaggio +- Update README.md (#189) +- Add cleanup in unsubscribe (#199) + +* add cleanup in unsubscribe + +* cleanup subscriber_task in client during unsubscribing + +* adding unit test + +--------- + +Co-authored-by: Daniele +- Update pip release with token (#218) + +* update pip release with token +--------- + +Signed-off-by: Gabriele Santomaggio +- Update pip release with token + +Signed-off-by: Gabriele Santomaggio +- Update ga + +Signed-off-by: Gabriele Santomaggio +- Add random name to the publish reference (#222) + +* Add a random name to the publisher reference. The reference is now unique across the cluster. Two publishers with the same ID and the same stream could enable involuntarily deduplication. With this fix, the name will be random. +* update version to 0.20.9 + +--------- +Signed-off-by: Gabriele Santomaggio +- Update deduplication example (#223) + +* udpate deduplication example + +--------- + +Signed-off-by: Gabriele Santomaggio +- Update README.md + +Fixes: https://github.com/rabbitmq-community/rstream/issues/226 +- Update to 0.21.0 (#230) + +* update to 0.21.0 +--------- + +Signed-off-by: Gabriele Santomaggio +- Update dependencies (#243) + +This PR updates project dependencies to their latest versions, including upgrading pytest-asyncio, flake8, mypy, pytest, black, and other development dependencies. Additionally, it updates the RabbitMQ Docker image and Poetry version in the CI workflow. + +Key changes: + +- Updates major dependency versions (pytest 7→8, flake8 3→7, mypy 0.910→1.18.2, pytest-asyncio 0.15.1→1.2.0) +- Migrates test fixtures from @pytest.fixture to @pytest_asyncio.fixture for async compatibility +- Temporarily disables flake8 and mypy checks in CI workflow + + +--------- + +Signed-off-by: Gabriele Santomaggio +Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> +- Adds CHANGELOG and git-cliff configuration +- *(ci)* Add workflows for release bumping and PR conventional commit validation +- Update commit parsers to prioritize GitHub PR labels for changelog grouping +- Update git-cliff setup in workflow +- Update tag pattern and skip tags regex +- Enhance version bumping and changelog configuration + +### Bug Fixes + +- Fix project name +- Fix Consumer handles subscribe offsets of NEXT and LAST +- Fix ci integration +- Fix circular imports +- Fix tests +- Fix publish pypi action (#51) +- Fixed a bug in offset computation (#71) +- Fixing a bug in send_sub_entry_batching (#93) + +* fixing a bug in send_sub_entry_batching + +* change sub entry example + +Signed-off-by: Gabriele Santomaggio + +* bump to 0.10.2 + +Signed-off-by: Gabriele Santomaggio + +--------- + +Signed-off-by: Gabriele Santomaggio +Co-authored-by: Gabriele Santomaggio +- Fixing publish confirmation for send_batch (#107) + +* fixing publish confirmation for send_batch + +* some print progress + +Signed-off-by: Gabriele Santomaggio + +* bump to 0.11.1 + +Signed-off-by: Gabriele Santomaggio + +--------- + +Signed-off-by: Gabriele Santomaggio +Co-authored-by: Gabriele Santomaggio +- *(client)* Fix cleanup of Client._waiters dict (#129) +- Fix the overflow error (#154) + +The publisher_id is an unsigned byte + +Signed-off-by: Gabriele Santomaggio +- Fixing examples, updated doc and bumping version (#167) +- Fixed a bug when, after unsubscribing, the next subscriber with the same subscriber name used a first subscriber callback and ignore second subscriber callback. (#204) + +* Actualized build and test section at README.md like ci. + +* Fixed a bug when, after unsubscribing, the next subscriber with the same subscriber name used a first subscriber callback and ignore second subscriber callback. +- Fixed a bug when in single_active_consumer mode and deliver frame with more than one message, the result of the consumer_update_listener function was ignored. (#206) +- Fixed a bug when subscriber frames not clears after unsubscribe (#211) +- Fixed a bug when used `consumer_update_listener` callback from another subscription in single active consumer mode. (#210) +- Fixed bugs of exception logging (#215) +- Fix for re-applying subscription filter on reconnect (#229) + +* Fix for re-applying subscription filter on reconnect + +When the reconnect_stream function runs a subscriber is recreated with +the existing subscriber setup. This did not include the original +filter configuration leading to the filtering quietly disappearing on +reconnect. + +Added filter_input to the `_Subscriber` object to track this configuration +and passed to the `create_subscriber` during `reconnect_stream` +- Fix `sasl_configuration_mechanism` for ClientPool. (#238) + +Existing implementation ignored setting of sasl_configuration_mechanism for ClientPool. Modified code to use `SlasMechanism.MechanismPlain` as default matching the existing functionality but to default to the provided value at the constructor for the new(), get(), and _resolve_broker() methods. +- Fix encoding long values with AMQP 1.0 encoder. (#240) + +* Fix encoding long values with AMQP 1.0 encoder. + +Adjusted integer encoding in `encode_unknown()` to encode a python int as either an int or long depending on whether the value is within range of AMQP 1.0 standard 32-bit signed integer. + +* Refactor: Use constants for 32-bit integer bounds in encoding logic. + +* Reorder INT32_MAX and INT32_MIN to be lexicographically sorted + +* chore: clarified comment that we're referring to **signed** 32-bit integers +- Fix subscribers list (#246) + +Fixes: https://github.com/rabbitmq-community/rstream/issues/241 + + +This PR refactors the consumer/subscriber system to use numeric IDs instead of string names for internal tracking, addressing issues with subscriber list management. The changes enhance performance and eliminate bugs associated with string-based subscriber identification. + +- Converts subscriber tracking from string-based names to integer-based IDs for better performance and reliability +- Updates MessageContext and EventContext to include stream information directly instead of requiring lookups +- Adds validation for max_subscribers_by_connection limits and introduces new exception types + + +Breaking changes +====== + +1. Subscriber returns not the `subscriber_id`, but instead the`reference` + +The bug was here [Tag 0.3.1]: +https://github.com/rabbitmq-community/rstream/blob/654a9ef23118d96098fe00861b3d661da7886030/rstream/consumer.py#L197-L203 + +Given two references with the same name the `subscriber = self._subscribers[reference]` is not consistent. + +With this PR the `_subscribers` is `[int, _Subscriber]` +```python +self._subscribers: dict[int, _Subscriber] = {} +``` + +Where the int is the subscriber id that _must_ be unique for connection by protocol. + +2. remove the `get_stream` function `message_context.consumer.get_stream(message_context.subscriber_name)` + +The `get_stream` is not needed anymore since the `stream` is now passed on the `message_context` and also `event_context` + +3. `subscribe_name` is now optional +```python +class MessageContext: + consumer: Consumer + stream: str + subscriber_id: int + subscriber_name: Optional[str] + offset: int + timestamp: int +``` +--------- + +Signed-off-by: Gabriele Santomaggio +- Fix typos and enhance README clarity + +Update for 0.40.0 +- Correct task_types format in PR Conventional Commit Validation workflow + +### Refactoring + +- Change the example to AMQP 1.0 + +rename a typo +- Change QPID to Azure AMQP +- Change repo link + +Signed-off-by: Gabriele Santomaggio +- Change type annotation from `list` to `Sequence` in `send_batch` and `send_sub_entry` methods to make variable covariant https://mypy.readthedocs.io/en/stable/generics.html#variance-of-generic-types (#219) + +### Testing + +- Test index issue +- Test index issue +- Test PR checks (#28) + +add PR checks +- Test fixing a timeout in test (#193) + +### Miscellaneous Tasks + +- Update version format in bump_main.yaml + +### Continuous Integration + +- Add tag_prefix to cliff.toml configuration + +### Attestations + +- False + + diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..02fdfce --- /dev/null +++ b/cliff.toml @@ -0,0 +1,126 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + +[bump] +features_always_bump_minor = true +breaking_always_bump_major = true +initial_tag = "0.1.0" +tag_prefix = "" + +[changelog] +# changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{% if commits | length > 0 %}\ +{% if ersion %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits %} + - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ + {% if commit.breaking %}[**breaking**] {% endif %}\ + {{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %} +{% endif %}\ +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailing whitespace from the templates +trim = true +# postprocessors +postprocessors = [ + # { pattern = '', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL +] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = false +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # Replace issue numbers + #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, + # Check spelling of the commit with https://github.com/crate-ci/typos + # If the spelling is incorrect, it will be automatically fixed. + #{ pattern = '.*', replace_command = 'typos --write-changes -' }, +] +# regex for parsing and grouping commits +commit_parsers = [ + # GitHub PR labels take precedence + { pr_labels = ["feature"], group = "Features" }, + { pr_labels = ["bug-fix"], group = "Bug Fixes" }, + { pr_labels = ["performance"], group = "Performance" }, + { pr_labels = ["documentation"], group = "Documentation" }, + { pr_labels = ["refactoring"], group = "Refactoring" }, + { pr_labels = ["styling"], group = "Styling" }, + { pr_labels = ["testing"], group = "Testing" }, + { pr_labels = ["chore"], group = "Miscellaneous Tasks" }, + { pr_labels = ["ci"], group = "Continuous Integration" }, + { pr_labels = ["build"], group = "Build System" }, + { pr_labels = ["reert"], group = "Reerts" }, + { pr_labels = ["security"], group = "Security" }, + { pr_labels = ["breaking change"], group = "Breaking Change" }, + # Conentional commits (lowercase) - fallback if no PR labels + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^perf", group = "Performance" }, + { message = "^doc", group = "Documentation" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + # Non-conentional commits (capitalized erbs) + { message = "^[Ff]ix(ed|es)?\\s", group = "Bug Fixes" }, + { message = "^[Aa]dd(ed|s)?\\s", group = "Features" }, + { message = "^[Uu]pdate(d|s)?\\s", group = "Features" }, + { message = "^[Cc]hange(d|s)?\\s", group = "Refactoring" }, + { message = "^[Rr]emoe(d|s)?\\s", group = "Refactoring" }, + { message = "^[Ii]mproe(d|s)?\\s", group = "Performance" }, + # Skip patterns + { message = "^(bump|jump|update) to [0-9]", skip = true }, + { message = "^?[0-9]+\\.[0-9]+", skip = true }, + { message = "^chore\\(release\\): prepare for", skip = true }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^Merge", skip = true }, + # Other conentional commits + { message = "^chore", group = "Miscellaneous Tasks" }, + { message = "^ci", group = "Continuous Integration" }, + { message = "^build", group = "Build System" }, + { message = "^reert", group = "Reerts" }, + { body = ".*security", group = "Security" }, +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = false +# regex for matching git tags +tag_pattern = "[0-9].*" +# regex for skipping tags (skip pre-release tags without content) +skip_tags = "[0-9]+\\.[0-9]+\\.[0-9]+-(rc|beta)\\.[0-9]+" +# regex for ignoring tags +ignore_tags = "" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" +# limit the number of commits included in the changelog. +# limit_commits = 42 + +[remote.github] +owner = "rabbitmq-community" +repo = "rstream"