Skip to content

chore(ci): pin toys to ~> 0.22.0 to restore green CI - #74

Merged
torreypayne merged 2 commits into
mainfrom
toys-alias-tool-fix
Sep 17, 2026
Merged

torreypayne merged 2 commits into
mainfrom
toys-alias-tool-fix

Conversation

@torreypayne

@torreypayne torreypayne commented Sep 17, 2026 •

Copy link
Copy Markdown
Member

What happened

CI installs toys unpinned, so the nightly scheduled run picks up whatever is newest on RubyGems. On 2026-09-11 that became 0.24.0, and every leg has died at tool-load since — at an unchanged SHA (745df42), with no commit from us.

From last night's run:

09:50:31  Successfully installed toys-core-0.24.0
09:50:31  Successfully installed toys-0.24.0
09:51:02  Error while loading tool file: undefined method `alias_tool' for #<Class id=0x140 tool=(root)> (NoMethodError)
09:51:02  while loading the root tool

Installed at 09:50:31, dead 31s later, before a single test ran. The line responsible:

run: "gem install --no-document toys && npm install linkinator"

Why 0.22.0

0.23 and 0.24 each broke us, in different ways:

toys alias_tool build
0.22.0 ✅ ✅
0.23.0 ✅ ❌ Could not find a gemspec
0.24.0 ❌ (above) ❌

0.22.0 is the only fully working release.

This PR

  1. Pins CI to ~> 0.22.0 — note ~> 0.22.0, not ~> 0.22, which would still admit 0.23 and 0.24.
  2. Swaps alias_tool :yard, :yardoc → tool "yard", delegate_to: "yardoc", which works on all three versions.

7/7 CI legs green. .toys.rb isn't in spec.files, so no gem contents change and no release.

toys 0.23.0 removed the `alias_tool` DSL directive as part of its 1.0
release-candidate refactor, and 0.24.0 followed two days later. CI
installs toys unpinned (`gem install --no-document toys`), so every leg
has failed with `undefined method 'alias_tool'` since that release
published -- at unchanged SHAs, with no code change of our own.

`tool "yard", delegate_to: "yardoc"` is accepted by both 0.22 and 0.24,
so this needs no version gate.
@torreypayne
torreypayne requested a review from a team as a code owner September 17, 2026 17:56
toys 0.23.0 and 0.24.0 each introduced an independent breaking change that
reds this repo's CI at unchanged SHAs, since toys was installed unpinned.

0.23.0 broke the `build` tool with "Could not find a gemspec"; 0.24.0
additionally removed the `alias_tool` directive. Verified matrix:

  toys 0.22.0  alias_tool PASS  build PASS
  toys 0.23.0  alias_tool PASS  build FAIL
  toys 0.24.0  alias_tool FAIL  build FAIL

0.22.0 is therefore the only fully working release, so there is no
intermediate version to pin to.
@torreypayne torreypayne changed the title chore: replace alias_tool with delegate_to for toys 0.23+ chore(ci): pin toys to ~> 0.22.0 to restore green CI Sep 17, 2026
@torreypayne
torreypayne merged commit 392d5e8 into main Sep 17, 2026
16 checks passed
@torreypayne
torreypayne deleted the toys-alias-tool-fix branch September 17, 2026 22:10
viacheslav-rostovtsev added a commit that referenced this pull request Sep 23, 2026
* fix(rest): only pass emit_defaults: to protobuf message #to_json

GrpcTranscoder#construct_body_query_params passed `emit_defaults: true`
to `to_json` on whatever the `body:` template resolved to. That keyword
belongs to Google::Protobuf::MessageExts#to_json; when the body template
points at a scalar, enum or repeated field the call instead dispatches to
the json gem's Object#to_json, which has never accepted it.

json 2.x silently discarded unknown keywords, so this was invisible. json
3.x validates them and raises ArgumentError, breaking transcoding at
runtime for any RPC with a scalar body binding. The gemspec does not
constrain json, so nothing prevents resolving 3.x.

Guard the keyword on the receiver actually being a protobuf message.
Behaviour is unchanged on json 2.x, where the keyword was always a no-op
on the non-message branch. The sibling call site that serialises the whole
request is safe and untouched: there the receiver is always a message.

Bug: b/565440846

* chore(deps): declare toys ~> 0.22.0 in the bundle

CI already pins toys to the 0.22.x series (#74), but nothing enforced it
for anyone running `toys ci` locally, so a stale or newer toys silently
produced different results than CI.

Declaring toys as a bundle dependency makes the pin self-enforcing:
Toys::Utils::Gems#check_gemfile_compatibility evaluates the Gemfile and
raises IncompatibleToysError when the running toys falls outside the
declared requirement, instead of failing later in a confusing way.

Note this does not make toys honour Gemfile.lock. Toys unconditionally
writes a temporary Gemfile that strips every already-loaded gem from the
dependency list and re-pins it to the exact version the toys process
loaded, so `toys test` still exercises the newest installed versions of
gems toys itself loads. Use `bundle exec` when lock fidelity matters.

Resolution is otherwise unaffected: the lockfile gains only toys and
toys-core, with no other version changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants