Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a81d467
Restructure into ably-pubsub-core and ably-pubsub-server gems
umair-ably Sep 1, 2026
84f75ae
Fix agent param spec to accept multi-digit version segments
umair-ably Sep 1, 2026
271e1b3
Stamp the side-declaring agent entry without a version
umair-ably Sep 2, 2026
69ba562
Rename the SDK agent identifier to ably-pubsub-ruby
umair-ably Sep 2, 2026
3997720
Update server gemspec homepage for the repo rename
umair-ably Sep 3, 2026
241e072
Add lockstep release workflow, update contributing and migration docs
umair-ably Sep 1, 2026
f51f78c
Add release dry-run job to CI
umair-ably Sep 1, 2026
9c16180
Add gem-packaging specs for the core/server split
umair-ably Sep 2, 2026
c24ba46
Signpost the old ably gem's API reference from the new docs front page
umair-ably Sep 4, 2026
fb8a171
Refactor client instantiation to enforce side-specific construction t…
ttypic Sep 14, 2026
4878f8f
Fix REST presence query params to use correct camelCase format (clien…
ttypic Sep 14, 2026
1d88899
Move client namespaces under Ably::PubSub and rename Rest to Http
ttypic Sep 16, 2026
bdcbd30
Raise when releasing a realtime channel that isn't detached (RTS4c-e)
SimonWoolf Oct 9, 2026
acfb1e5
core: replace host options with endpoint client option
ttypic Oct 9, 2026
59eff05
Add update_message support for REST and Realtime channels
matt423 Feb 27, 2026
0d04e03
Add PublishResult for REST and Realtime publish (RSL1n)
matt423 Feb 27, 2026
166e925
Add delete_message for REST and Realtime channels (RSL15/RTL32)
matt423 Feb 27, 2026
f7e2014
Add append_message for REST and Realtime channels (RSL15/RTL32)
matt423 Feb 27, 2026
0c7b72b
Rewrite Stats model to match spec v2.1+ (TS12)
matt423 Mar 2, 2026
8ea4f4e
Document publish result and Stats changes in the 2.0 migration guide
matt423 Feb 27, 2026
844f062
Fix EventMachine test pollution causing cascade failures
matt423 Mar 2, 2026
e30fc7a
Merge pull request #450 from ably/protocal-v5
ttypic Oct 19, 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
37 changes: 37 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,43 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
flag-name: ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }}
parallel: true
# Dry run of the release pipeline: the same consistency assertions release.yml's
# pre-flight makes, plus a build of both gems — so a version-file or gemspec
# regression surfaces on every PR instead of at release time. Publishes nothing.
release-dry-run:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
with:
persist-credentials: false
- uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
with:
ruby-version: '3.3'
bundler-cache: false
- name: 'Versions and pin must agree (mirrors release.yml pre-flight)'
run: |
ruby <<'RUBY'
require_relative 'core/lib/ably/version'
require_relative 'server/lib/ably/pubsub/server/version'

errors = []
errors << "core Ably::VERSION (#{Ably::VERSION}) != server Ably::PubSub::Server::VERSION (#{Ably::PubSub::Server::VERSION})" unless Ably::VERSION == Ably::PubSub::Server::VERSION

server_spec = Gem::Specification.load('server/ably-pubsub-server.gemspec')
core_dep = server_spec.dependencies.find { |d| d.name == 'ably-pubsub-core' }
errors << "server gemspec pins ably-pubsub-core '#{core_dep&.requirement}', expected '= #{Ably::VERSION}'" unless core_dep&.requirement.to_s == "= #{Ably::VERSION}"

abort errors.join("\n") unless errors.empty?
puts "Version consistency OK: #{Ably::VERSION}"
RUBY
- name: Build both gems
run: |
set -euo pipefail
(cd core && gem build ably-pubsub-core.gemspec)
(cd server && gem build ably-pubsub-server.gemspec)

finish:
needs: check
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "lib/submodules/ably-common"]
path = lib/submodules/ably-common
path = core/lib/submodules/ably-common
url = https://github.com/ably/ably-common.git
2 changes: 2 additions & 0 deletions .yardopts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
core/lib/**/*.rb
server/lib/**/*.rb
41 changes: 29 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
# Contributing

This repository hosts two gems, released in lockstep at the same version:

- [`core/`](./core) — `ably-pubsub-core`: the shared implementation. An internal package; only Ably packages depend on it.
- [`server/`](./server) — `ably-pubsub-server`: the public server-side package. Its factory functions (`Ably::PubSub::Server.create_http_client` / `.create_realtime_client`) are the only entry points: the client classes refuse direct construction, and these factories reach them through `Ably::Internal`.

## Development

1. Fork it
2. When pulling to local, make sure to also pull the `ably-common` repo (`git submodule init && git submodule update`)
3. Create your feature branch (`git checkout -b my-new-feature`)
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Ensure you have added suitable tests and the test suite is passing(`bundle exec rspec`)
5. Ensure you have added suitable tests and the test suite is passing (`bundle exec rspec`) — the root `Gemfile` wires both gems up as path dependencies, so a single `bundle install` at the root covers everything
6. Push to the branch (`git push origin my-new-feature`)
7. Create a new Pull Request

---

## Release process

This library uses [semantic versioning](http://semver.org/). For each release, the following needs to be done:
This library uses [semantic versioning](http://semver.org/). `ably-pubsub-core` and `ably-pubsub-server` always release together at the same version: the release workflow refuses to publish them independently.

For each release, the following needs to be done:

1. Create a branch for the release, named like `release/1.2.3` (where `1.2.3` is the new version number)
2. Update the version number in [version.rb](./lib/ably/version.rb) and commit the change.
1. Create a branch for the release, named like `release/2.0.1` (where `2.0.1` is the new version number)
2. Update the version number in **all three places**, which must agree (the release workflow's pre-flight enforces this):
- `Ably::VERSION` in [core/lib/ably/version.rb](./core/lib/ably/version.rb)
- `Ably::PubSub::Server::VERSION` in [server/lib/ably/pubsub/server/version.rb](./server/lib/ably/pubsub/server/version.rb)
- the exact-version `ably-pubsub-core` pin in [server/ably-pubsub-server.gemspec](./server/ably-pubsub-server.gemspec) (derived from the version constant, so it normally follows automatically)
3. Run [`github_changelog_generator`](https://github.com/github-changelog-generator/github-changelog-generator) to automate the update of the [CHANGELOG](./CHANGELOG.md). This may require some manual intervention, both in terms of how the command is run and how the change log file is modified. Your mileage may vary:
- The command you will need to run will look something like this: `github_changelog_generator -u ably -p ably-pubsub-ruby --since-tag v1.2.3 --output delta.md --token $GITHUB_TOKEN_WITH_REPO_ACCESS`. Generate token [here](https://github.com/settings/tokens/new?description=GitHub%20Changelog%20Generator%20token).
- The command you will need to run will look something like this: `github_changelog_generator -u ably -p ably-pubsub-ruby --since-tag v2.0.0 --output delta.md --token $GITHUB_TOKEN_WITH_REPO_ACCESS`. Generate token [here](https://github.com/settings/tokens/new?description=GitHub%20Changelog%20Generator%20token).
- Using the command above, `--output delta.md` writes changes made after `--since-tag` to a new file
- The contents of that new file (`delta.md`) then need to be manually inserted at the top of the `CHANGELOG.md`, changing the "Unreleased" heading and linking with the current version numbers
- Also ensure that the "Full Changelog" link points to the new version tag instead of the `HEAD`
4. Commit this change: `git add CHANGELOG.md && git commit -m "Update change log."`
5. Ideally, run `rake doc:spec` to generate a new [spec file](./SPEC.md). Then commit these changes.
6. Make a PR against `main`. Once the PR is approved, merge it into `main`.
7. Add a tag to the new `main` head commit and push to origin such as `git tag v1.0.3 && git push origin v1.0.3`.
8. Visit [https://github.com/ably/ably-pubsub-ruby/tags](https://github.com/ably/ably-pubsub-ruby/tags) and `Add release notes` for the release including links to the changelog entry.
9. Run `rake release` to publish the gem to [Rubygems](https://rubygems.org/gems/ably).
10. Release the [REST-only library `ably-ruby-rest`](https://github.com/ably/ably-ruby-rest#release-process).
11. Create the entry on the [Ably Changelog](https://changelog.ably.com/) (via [headwayapp](https://headwayapp.co/)).
7. Add a tag to the new `main` head commit and push to origin such as `git tag v2.0.1 && git push origin v2.0.1`.
8. Visit [the tags page](https://github.com/ably/ably-pubsub-ruby/tags) and `Add release notes` for the release including links to the changelog entry.
9. Run the [Release workflow](./.github/workflows/release.yml) (Actions → Release → Run workflow) with the version number. It publishes `ably-pubsub-core` and then `ably-pubsub-server` to RubyGems via trusted publishing — no local credentials involved. A failed run is safe to re-run with the same version: already-published gems are skipped.
10. Create the entry on the [Ably Changelog](https://changelog.ably.com/) (via [headwayapp](https://headwayapp.co/)).

### Trusted publishing

The workflow authenticates to RubyGems with [trusted publishing](https://guides.rubygems.org/trusted-publishing/) (GitHub OIDC): both gems have a Trusted Publisher configured on rubygems.org bound to this repository and `.github/workflows/release.yml`. There are no long-lived RubyGems API keys anywhere. If the repository is renamed, both bindings must be reconfigured on rubygems.org or publishing fails.

### The legacy `ably` gem

The `ably` gem is in its maintenance window (security and critical fixes only, released from the maintenance branch) and is **not** released from `main`. The `ably-rest` gem (from the `ably-ruby-rest` repo) is likewise in maintenance and no longer part of this release process.
7 changes: 5 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in ably.gemspec
gemspec
# This repo hosts two gems, released in lockstep at the same version (PDR-091b):
# - core/ ably-pubsub-core: the shared implementation (internal package)
# - server/ ably-pubsub-server: the public server-side package (factory entry points)
gemspec path: 'core'
gemspec path: 'server'
5 changes: 5 additions & 0 deletions INTRO.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Ably `Ruby` Client Library SDK API Reference

> **Using the `ably` gem?** This is the API reference for the `ably-pubsub-server` gem, which replaces it.
> The API reference for the maintenance-only `ably` gem remains available at
> [sdk.ably.com/builds/ably/ably-ruby/main/docs](https://sdk.ably.com/builds/ably/ably-ruby/main/docs/)
> until its end of life.

The `Ruby` Client Library SDK supports a realtime and a REST interface.

The realtime interface enables a client to maintain a persistent connection to Ably and publish, subscribe and be present on channels.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ To use the Ably Realtime SDK in Ruby, the `EventMachine` reactor loop must be ru
Wrap your code inside a `EventMachine.run` block:

```ruby
require 'ably'
require 'ably/pubsub/server'

EventMachine.run do
client = Ably::Realtime.new(key: 'your-api-key')
client = Ably::PubSub::Server.create_realtime_client(key: 'your-api-key')

client.connection.connect do
puts "Connected with connection ID: #{client.connection.id}"
Expand All @@ -87,7 +87,7 @@ The following code connects to Ably's realtime messaging service, subscribes to

```ruby
# Initialize Ably Realtime client
realtime_client = Ably::Realtime.new(key: 'your-ably-api-key', client_id: 'me')
realtime_client = Ably::PubSub::Server.create_realtime_client(key: 'your-ably-api-key', client_id: 'me')

# Wait for connection to be established
realtime_client.connection.on(:connected) do
Expand Down
6 changes: 3 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'rubygems'
require 'bundler/setup'
require 'bundler/gem_tasks'

require 'json'

require 'yard'
Expand Down Expand Up @@ -32,8 +32,8 @@ begin

desc 'Generate error code constants from ably-common: https://github.com/ably/ably-common/issues/32'
task :generate_error_codes do
errors_json_path = File.join(File.dirname(__FILE__), 'lib/submodules/ably-common/protocol/errors.json')
module_path = File.join(File.dirname(__FILE__), 'lib/ably/modules/exception_codes.rb')
errors_json_path = File.join(File.dirname(__FILE__), 'core/lib/submodules/ably-common/protocol/errors.json')
module_path = File.join(File.dirname(__FILE__), 'core/lib/ably/modules/exception_codes.rb')
max_length = 0

errors = JSON.parse(File.read(errors_json_path)).each_with_object({}) do |(key, val), hash|
Expand Down
Loading
Loading