ci: add concurrency limits to all workflows - #100
Merged
Merged
Conversation
This was referenced Apr 8, 2026
Collaborator
Author
ApprovabilityVerdict: Unable to determine Macroscope's correctness review was unable to post its findings for this PR. Approvability cannot proceed without a successful correctness review. You can customize Macroscope's approvability policy. Learn more. |
Collaborator
Author
neekolas
changed the base branch from
04-04-use_xnet_for_backend_startup
to
graphite-base/100
April 8, 2026 17:10
macroscopeapp
Bot
dismissed
their stale review
April 8, 2026 17:10
Dismissing prior approval to re-evaluate baa3424
macroscopeapp
Bot
dismissed
their stale review
April 8, 2026 17:11
Dismissing prior approval to re-evaluate baa3424
Cancel in-progress runs when a new push arrives on the same PR branch. Uses github.run_id fallback for main branch pushes so they don't cancel each other. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
neekolas
force-pushed
the
04-08-concurrency_limits_on_actions
branch
from
April 8, 2026 17:12
baa3424 to
dc17e2a
Compare
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
concurrencygroups to all four CI workflows (buf, lint, test, push)github.run_idas the group key so they run independentlyWhy
Without concurrency limits, every push to a PR branch queues a new set of workflow runs. This wastes CI resources on stale commits and can cause unnecessary load on shared runners.
How it works
github.head_refis the branch name, so all runs for the same branch share one group per workflow.cancel-in-progress: truekills the older run.github.head_refis empty, so it falls back togithub.run_id(unique per run), meaning main pushes never cancel each other.Test plan
🤖 Generated with Claude Code
Note
Add concurrency limits to CI workflows and add V4 notification listener with binary topic support
concurrencygroups withcancel-in-progress: trueto all GitHub Actions workflows (buf.yml, lint.yml, push.yml, test.yml) to prevent redundant runs.V4Listenerthat subscribes to the xmtpv4NotificationApi, alongside the existing V3Listener; the active listener is selected at startup via a newLISTENER_TYPEenv var (defaultv3).TEXTtoBYTEAin Postgres (migration 00004), converting existing rows and removing non-conforming entries.payload_formatcolumn to installations (migration 00005) and propagates it through registration, delivery (APNS/FCM payloads), and JSON serialization./readyzHTTP endpoint on the API server that returns 503 when the active listener is not ready.docker-compose.ymlwith an externalxnetnetwork;dev/upanddev/downnow orchestrate viaxnet-cli.📊 Macroscope summarized baa3424. 41 files reviewed, 12 issues evaluated, 8 issues filtered, 0 comments posted
🗂️ Filtered Issues
cmd/server/main.go — 0 comments posted, 1 evaluated, 1 filtered
opts.Api.Enabledis true butopts.Xmtp.ListenerEnabledis false,notifListenerwill benil, soapiServer.SetReadyCheckis never called ands.readyCheckremainsnil. The/readyzendpoint is always registered (line 67 inStart()), so if the handler callss.readyCheck()without a nil check, it will panic. This path is reachable: run with--apibut without--xmtp-listener, then request/readyz. [ Cross-file consolidated ]pkg/delivery/http_test.go — 0 comments posted, 1 evaluated, 1 filtered
interfaces.SendRequesthas all fields tagged withjson:"-", meaningjson.Marshal(req)produces{}. The assertionrequire.Equal(t, "v4", p["payload_format"])will fail sincepwill be an empty map with nopayload_formatkey. [ Out of scope (triage) ]pkg/interfaces/interfaces.go — 0 comments posted, 1 evaluated, 1 filtered
ValidateForListenerat line 90 only checkslistenerType == ListenerTypeV3(i.e., the string"v3"). Incmd/server/main.go, whenopts.Xmtp.ListenerTypeis empty or any value other than"v4", thedefaultbranch creates a V3 listener, butinterfaces.ListenerType(opts.Xmtp.ListenerType)is passed as-is (e.g.,ListenerType("")) to theApiServer. Since""!=ListenerTypeV3("v3"), the validation inValidateForListenernever triggers, allowing V4 payload format registrations on what is actually a V3 listener. This bypasses the intended format compatibility check. [ Out of scope ]pkg/testutils/delivery.go — 0 comments posted, 1 evaluated, 1 filtered
GetSendRequestsat line 47 readsm.Calls(a slice onmock.Mock) without holding the mock's mutex. In the test usage pattern,GetSendRequestsis called afterRequireEventuallySendCountconfirms the counter reached the expected value, but theRuncallback increments the atomic counter beforemock.Mockinternally appends tom.Calls(the append happens afterRunreturns). This means the counter can reachwantwhile the lastCallentry has not yet been written tom.Calls, causingGetSendRequeststo return fewer entries than expected and the subsequentrequire.Lento fail intermittently. [ Out of scope ]pkg/topics/topics.go — 0 comments posted, 1 evaluated, 1 filtered
strings.TrimPrefixreturns the string unchanged when the prefix is absent, soParseV3Topicsilently parses topic strings that lack the requiredV3_PREFIX(e.g.,"g-abc123/proto"without the leading/xmtp/mls/1/). The function does not verify the prefix was actually present, potentially allowing malformed topics to be parsed as valid V3 topics if a caller omits the prefix check. [ Posting failed ]pkg/xmtp/v4_listener.go — 0 comments posted, 3 evaluated, 3 filtered
startEnvelopeListenerreadsl.v4Clientat line 109 without holdingl.connMu, whilerefreshV4Clientwritesl.v4Clientat line 387 underl.connMu. SincerefreshV4Clientis called from bothstartEnvelopeListener(line 114) andconsumeEnvelopeStream(line 146) — and the subsequent read ofl.v4Clientat line 109 happens outside the lock — this is a data race on a non-atomic field. The Go memory model does not guarantee the read at line 109 will see the value written at line 387 without proper synchronization. [ Failed validation ]buildV3SendRequest, when handling*envelopesProto.ClientEnvelope_GroupMessage, the code callspayload.GroupMessage.GetV1()at line 311 and immediately passes the result toconvertGroupMessageToV3without checking ifv1Inputis nil. IfGetV1()returns nil (e.g., if the GroupMessage contains a different version variant),convertGroupMessageToV3will panic when dereferencinginput.Data,input.SenderHmac, andinput.ShouldPush. In contrast,buildV4SendRequestpasses the result tobuildGroupMessageContextwhich does handle nil input. The V3 path should either check for nil before callingconvertGroupMessageToV3or return an appropriate error likeErrUnknownPayloadType. [ Posting failed ]refreshV4Client, the old connectionl.v4Connis closed at line 381 before verifying thatNewV4Clientsucceeds. IfNewV4Clientreturns an error at line 384, the function returns without updatingl.v4Clientorl.v4Conn, leavingl.v4Clientpointing to a client backed by the now-closed connection. Subsequent calls tol.v4Client.SubscribeAllEnvelopesinstartEnvelopeListenerwill fail until a retry eventually succeeds. The fix is to only close the old connection after successfully creating the new client. [ Posting failed ]