Add cross-repo upstream-gating workflow#29
Merged
Conversation
Runs app-main + octi-desktop consumer suites against every octi-web PR's HEAD when wire-format-relevant paths change. A serializer change that drops a required field, retypes a value, or renames an enum entry is blocked at this PR rather than caught later when a consumer happens to bump its pin. Also routes the fixture generator's connector IDs through octiServerConnectorId() so a change to src/protocol/connector-id.ts propagates into the committed fixtures; without this the function could drift while the fixtures kept the old format. Pairs with octi#318 + octi-desktop#46 (the two consumers, both merged).
3 tasks
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.
What changed
No user-facing behavior change. Internal: octi-web's PRs now run app-main and octi-desktop's consumer test suites against the PR's HEAD when wire-format-relevant paths change. A serializer change that drops a required field, retypes a value, or renames an enum entry is blocked at THIS PR rather than discovered later when a consumer happens to bump its pin.
Mirror of the same gate on app-main (
d4rken-org/octi#315, merged) — now that both consumers ship support for consuming octi-web's published fixtures (d4rken-org/octi#318+d4rken-org/octi-desktop#46, both merged), the symmetric direction can land safely.Technical Context
src/modules/,src/__interop__/published/,src/protocol/connector-id.ts,src/util/base64.ts,tools/generate-fixtures.ts, and the workflow file itself.src/crypto/,src/protocol/octi-api.ts,src/linking/are deliberately NOT in scope — they don't have committed fixtures that consumers exercise. Adding more means adding more producer-side fixtures first.octiServerConnectorId()(Codex finding). The fixture generator previously hardcodedkserver-prod.kserver.octi.darken.eu-aaaa...literals; the actual production functionoctiServerConnectorId(server, accountId)builds them at runtime. Hardcoding let the function drift while the fixtures kept the old format, masking a wire-format break. Now the generator imports the function +OFFICIAL_SERVERS.PROD/BETA, computes the IDs, and gets byte-identical output (verified via re-runningpnpm fixtures:generate— zero churn in the committed JSON). Net effect: a future change tooctiServerConnectorId()propagates into the fixtures and trips the producer self-check in the same PR.verify-octiselective task set. Runs only:modules-meta:testDebugUnitTest,:modules-clipboard:testDebugUnitTest,:modules-files:testDebugUnitTeston app-main — the modules that actually consume octi-web's published fixtures. Full:testwould build app + UI variants that don't exercise the contract; would waste ~10 minutes per PR for no signal.INTEROP_FIXTURE_OVERRIDES='{"d4rken-org/octi-web":"<head sha>"}'. The multi-source resolver on both consumers drops the lockedmanifest_sha256trust anchor for an overridden source; per-file sha256s in the freshly-fetched manifest stay as the anchor.${{ runner.os }}-app-main-gradle-caches-…and${{ runner.os }}-octi-desktop-gradle-caches-…so the two jobs never restore each other's incompatible caches.Review guidance
.github/workflows/cross-repo-verify.yml(same shape, opposite direction). Concurrency group, allowlist match function, JDK setup, and override env should match the spirit.actions/checkoutofhead.shaworks for same-repo branches only. Fork PRs get a clean failure in the verify job (raw fetch of fork-only SHA returns 404). Documented in.claude/rules/testing.md.Test plan
python3 -c "import yaml; yaml.safe_load(...)"green)pnpm fixtures:generateproduces zero diff against committed JSON;vitest run src/__interop__/published-self-check.test.ts14/14 passtools/generate-fixtures.tsis touched. Expected: bothverify-octiandverify-desktopjobs detect the relevant change, check out the consumer at default branch, set the override, run the consumer suite, and pass.Sister PRs: