diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e76fd9..b97d352 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,7 +66,7 @@ jobs: timeout-minutes: 15 services: redis: - image: public.ecr.aws/docker/library/redis:7 + image: mirror.gcr.io/library/redis:7 ports: - 6379:6379 options: >- @@ -87,7 +87,7 @@ jobs: timeout-minutes: 15 services: postgres: - image: public.ecr.aws/docker/library/postgres:18 + image: mirror.gcr.io/library/postgres:18 env: POSTGRES_USER: solid_objects POSTGRES_PASSWORD: solid_objects @@ -121,7 +121,7 @@ jobs: client: [ mysql2, trilogy ] services: mysql: - image: public.ecr.aws/docker/library/mysql:8.4 + image: mirror.gcr.io/library/mysql:8.4 env: MYSQL_USER: solid_objects MYSQL_PASSWORD: solid_objects diff --git a/CHANGELOG.md b/CHANGELOG.md index 0afce2e..f25aaa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.0.3 - 2026-10-18 + +- Add `docs/maintenance.md`. It tells you who maintains the gem, how CI checks + each change, how a release is published, what you keep if maintenance + stops, and how to become a maintainer. The README and the comparison pages + now link to this page. They and `docs/versioning.md` no longer state a count + of maintainers. A new test fails when a page states one. + ## 1.0.2 - 2026-10-15 - Add two comparison pages in `docs/compare/`: Solid Queue diff --git a/Gemfile.lock b/Gemfile.lock index d70dd17..a1391f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - solid_objects (1.0.2) + solid_objects (1.0.3) actioncable (>= 7.1) actionpack (>= 7.1) actionview (>= 7.1) @@ -392,7 +392,7 @@ CHECKSUMS rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 - solid_objects (1.0.2) + solid_objects (1.0.3) sqlite3 (2.9.5-aarch64-linux-gnu) sha256=78075b6337d3d182c6d2b4691049ed45cd220826160c9ea18946bf6a1de200dc sqlite3 (2.9.5-aarch64-linux-musl) sha256=18c801185deb4adc01ddb281e8f672a39e3d1729979ca91e39439cd3eac0402d sqlite3 (2.9.5-arm-linux-gnu) sha256=1bdfca0c7d63998c60b0f4a8e3c8df2d33800ccc4abd2d612eddbbbc92a4c48b diff --git a/README.md b/README.md index 83bb3d1..6fee179 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ model and when to use it. **Status.** Version 1.0: the public API follows semantic versioning and does not break before 2.0. [Versioning](docs/versioning.md) gives the limits of the -promise. First public release: August 6, 2026. One maintainer. +promise. First public release: August 6, 2026. **Production use.** One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No @@ -199,6 +199,7 @@ every claim in [`test/guides/`](test/guides/): - [Reminders](docs/reminders.md) - [Reactive ERB](docs/realtime.md) - [Detailed architecture](docs/architecture.md) +- [Maintenance and continuity](docs/maintenance.md) - [Detailed documentation](docs/) The dashboard, benchmarks, migration cookbook, schema, and exhaustive API diff --git a/docs/compare/good-job.md b/docs/compare/good-job.md index 035b57c..410c01c 100644 --- a/docs/compare/good-job.md +++ b/docs/compare/good-job.md @@ -210,7 +210,7 @@ How it works: - First public release: August 6, 2026. - Version 1.0.0: October 13, 2026. The public API follows [semantic versioning](../versioning.md). -- One maintainer. +- [Maintenance and continuity](../maintenance.md) tells you who maintains the project and how a release is made. - One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. - The [benchmarks](../benchmarks.md) are development measurements. Longer soak tests are open work. diff --git a/docs/compare/solid-queue.md b/docs/compare/solid-queue.md index 1a9bc8a..40af371 100644 --- a/docs/compare/solid-queue.md +++ b/docs/compare/solid-queue.md @@ -205,7 +205,7 @@ How it works: - First public release: August 6, 2026. - Version 1.0.0: October 13, 2026. The public API follows [semantic versioning](../versioning.md). -- One maintainer. +- [Maintenance and continuity](../maintenance.md) tells you who maintains the project and how a release is made. - One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. - The [benchmarks](../benchmarks.md) are development measurements. Longer soak tests are open work. diff --git a/docs/comparisons.md b/docs/comparisons.md index 779c741..2b3abf6 100644 --- a/docs/comparisons.md +++ b/docs/comparisons.md @@ -23,4 +23,4 @@ The problem guides start from the same choices: ## Status -Solid Objects 1.0.0 shipped on October 13, 2026. The first public release was on August 6, 2026. It has one maintainer. One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. See [versioning](versioning.md). +Solid Objects 1.0.0 shipped on October 13, 2026. The first public release was on August 6, 2026. One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. No production use by other people is known. See [versioning](versioning.md) and [maintenance and continuity](maintenance.md). diff --git a/docs/maintenance.md b/docs/maintenance.md new file mode 100644 index 0000000..aa3b576 --- /dev/null +++ b/docs/maintenance.md @@ -0,0 +1,65 @@ +# Maintenance and continuity + +This page tells you who maintains Solid Objects, how a release is made, and +what you keep if maintenance stops. It also tells you how to help maintain the +project. + +## Who maintains it + +Lucas Carlson ([@cardmagic](https://github.com/cardmagic)) is the lead +maintainer of the Ruby gem `solid_objects` and of the npm package +[`solid-objects`](https://github.com/cardmagic/solid-objects-js). The two +packages use the same model and the same correctness contract. A change to the +model goes into both packages, and the +[parity ledger](https://github.com/cardmagic/solid-objects-js/blob/main/docs/parity.md) +records each difference between them. + +The same maintainer sells [Solid Objects Pro](https://solidobjects.pro), a +commercial package that batches operations at scale. Pro depends on this gem. +This gem does not depend on Pro, and it needs no account, license key, or +service from the maintainer. + +## How a change is checked + +CI runs on each push and each pull request: + +- The full test suite on SQLite, on each pair of Ruby 3.3, 3.4, or 4.0 and + Rails 7.1, 7.2, 8.0, or 8.1. +- The full test suite on PostgreSQL and on MySQL, with both MySQL clients. +- Standard, RuboCop, RBS, Steep, and Brakeman. + +[Compatibility and maturity](virtual-actors.md#compatibility-and-maturity) +lists the supported versions. The [correctness contract](correctness.md) lists +the guarantees that the tests check. + +## How a release is made + +1. The maintainer pushes a version tag, for example `v1.0.3`. +2. GitHub Actions runs all test jobs again on that tag. +3. If all test jobs pass, GitHub Actions builds the gem and pushes it to + RubyGems with trusted publishing. The repository keeps no RubyGems key. +4. The same job makes a GitHub release and attaches the gem file. + +[Versioning](versioning.md) tells you what a release can change. +`CHANGELOG.md` lists each release. + +## What you keep if maintenance stops + +- **Your data.** Actor state, mailboxes, reminders, and effects are rows in + your application's database. [Database schema](database-schema.md) describes + each table. No service of the maintainer holds your data. +- **The code.** The [MIT License](../MIT-LICENSE) lets anyone use, change, + fork, and publish the code. +- **The checks.** The tests and the CI configuration are in this repository. A + fork can check its changes with the same suite. + +## Help maintain Solid Objects + +The project wants more maintainers. Experience with Rails, with locks and +transactions in PostgreSQL or MySQL, or with TypeScript and Node.js helps. + +1. Read [CONTRIBUTING.md](../CONTRIBUTING.md). +2. Send a small pull request: a fix, a test, or a correction to a guide. +3. After some of your pull requests are merged, open an + [issue](https://github.com/cardmagic/solid-objects-ruby/issues) to ask to + become a maintainer. diff --git a/docs/versioning.md b/docs/versioning.md index 7953a53..d0d4403 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -41,8 +41,8 @@ lists the current minimum versions. Version 1.0 is a promise about the API. It is not a claim of measured scale. The [benchmarks](benchmarks.md) are development measurements and do not -guarantee capacity. Longer soak tests are open work. The project has one -maintainer, and no production use by other people is known. +guarantee capacity. Longer soak tests are open work. No production use by +other people is known. ## Releases before 1.0 diff --git a/lib/solid_objects/version.rb b/lib/solid_objects/version.rb index 5feb868..9e25219 100644 --- a/lib/solid_objects/version.rb +++ b/lib/solid_objects/version.rb @@ -1,5 +1,5 @@ # rbs_inline: enabled module SolidObjects - VERSION = "1.0.2" + VERSION = "1.0.3" end diff --git a/test/unit/maintenance_documents_test.rb b/test/unit/maintenance_documents_test.rb new file mode 100644 index 0000000..4b773fe --- /dev/null +++ b/test/unit/maintenance_documents_test.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "test_helper" + +class MaintenanceDocumentsTest < ActiveSupport::TestCase + ROOT = File.expand_path("../..", __dir__) + MAINTAINER_COUNT = /\b(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|only|sole|single)\s+maintainers?\b/i + + def guide(path) + File.read(File.join(ROOT, path)) + end + + test "the README links to the maintenance page" do + assert_includes guide("README.md"), "(docs/maintenance.md)" + end + + test "the maintenance page names the lead maintainer" do + assert_match( + %r{Lucas Carlson \(\[@cardmagic\]\(https://github\.com/cardmagic\)\) is the lead\s+maintainer}, + guide("docs/maintenance.md") + ) + end + + test "the count pattern finds a count of maintainers in each form" do + [ "One maintainer.", "1 maintainer", "two maintainers", "the only\nmaintainer" ].each do |text| + assert_match MAINTAINER_COUNT, text + end + [ "the lead maintainer", "wants more maintainers", "become a maintainer" ].each do |text| + refute_match MAINTAINER_COUNT, text + end + end + + test "no page states a count of maintainers" do + paths = [ "README.md", "CONTRIBUTING.md", *Dir.glob("docs/**/*.md", base: ROOT).sort ] + pages = paths.select { |path| guide(path).match?(MAINTAINER_COUNT) } + + assert_empty pages + end + + test "the maintenance page tells a contributor how to start" do + assert_includes guide("docs/maintenance.md"), "(../CONTRIBUTING.md)" + end +end