Fix #29: robust openclaw_version parser (handles 5.6+ output format)#33
Merged
Conversation
The previous parser used `Str::after($output, 'openclaw ')` which only matched the lowercase-prefix format and silently dropped the value when the binary's output changed format between releases. Servers provisioned on 5.6+ ended up with empty `servers.openclaw_version` columns, breaking version-conditional code paths (ChatGPTAuthService::ensureMinimumOpenClawVersion). Extracted the parsing into a static `parseOpenClawVersion` helper that handles every observed format with a single regex: - "openclaw v2026.3.8" (≤5.5, lowercase + v prefix) - "openclaw 2026.5.6 (c97b9f7)" (5.6+, lowercase + build hash) - "OpenClaw 2026.5.19" (capital O, no prefix) - "v2026.5.19" / "2026.5.19" (bare) - "openclaw 2026.5.20-beta.1" (prerelease) When the parser returns null we now log the raw output so the next unknown format is debuggable instead of silently disappearing. The ipv4_address and provider_server_id concerns from the original ticket were a false alarm — both columns were populated correctly by `ProvisionDigitalOceanServerJob`; the reporter was querying with wrong column names (server.ip, server.cloud_resource_id) in tinker. This commit only addresses the openclaw_version capture. Tests: 9 new unit tests covering every observed output format plus the failure path. Full suite: 172 passed, 4 skipped. Fixes #29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The previous parser used
Str::after($output, 'openclaw ')which only matched the lowercase-prefix format with a literalvafter — fine for≤ 5.5but it silently produced an empty version string when OpenClaw 5.6+ changed the output format. The conditionalif ($version) { ... update(...) }then skipped the DB write, leavingservers.openclaw_versionempty after every successful provision. This broke version-conditional code paths likeChatGPTAuthService::ensureMinimumOpenClawVersion, which then unnecessarily upgraded openclaw on every ChatGPT pairing.Fixes #29.
Scope correction
The original ticket also flagged
server.ipandserver.cloud_resource_idas empty. That was a false alarm: those columns don't exist by those names — the real columns areipv4_addressandprovider_server_id, both of whichProvisionDigitalOceanServerJobpopulates correctly (:60-63). My tinker probe used the wrong names; the data was always there. This PR addresses only the real bug (openclaw_version). The ticket has been corrected.Changes
SetupOpenClawOnServerJob::parseOpenClawVersion(new, public static): single regex(\d{4}\.\d+\.\d+(?:[-.][a-z0-9.]+)?)that captures the version token regardless of casing or prefix and strips a leadingvfrom the match.captureOpenClawVersion: delegates to the new parser and logs the raw output when parsing fails, so future format changes are debuggable instead of silently dropping the value.Formats covered
openclaw v2026.3.82026.3.8openclaw 2026.5.6 (c97b9f7)2026.5.6openclaw 2026.5.19 (abc1234)2026.5.19OpenClaw 2026.5.192026.5.19v2026.5.192026.5.192026.5.192026.5.19openclaw 2026.5.20-beta.12026.5.20-beta.1"Warning: foo\nopenclaw 2026.5.19 (abc)"2026.5.19""/"command not found"/"openclaw"nullTests
9 new unit tests in
tests/Unit/Jobs/SetupOpenClawOnServerJobTest.php. Full suite:Pint: clean.
Live E2E status
server.status=runningphp artisan tinker --execute='echo App\Models\Server::latest()->first()->openclaw_version;'OPENCLAW_VERSION(e.g.2026.5.19)Out of scope (filed separately if needed)
ServerSetupScriptService.php:105usessed "s/openclaw //"inline for journaling — same brittle parser pattern, but it's a shell-side variable not used for the DB column. Could be hardened in a follow-up.ChatGPTAuthService.php:230uses a different regex tailored to its capital-O assumption — works for now but worth aligning with this parser eventually.Test plan
servers.openclaw_versionis populated after a fresh DO provision