Skip to content

feat(cloud): device matrix via repeated --ios-config/--android-config…#75

Open
finalerock44 wants to merge 3 commits into
devfrom
feat/1105-device-matrix-cli
Open

feat(cloud): device matrix via repeated --ios-config/--android-config…#75
finalerock44 wants to merge 3 commits into
devfrom
feat/1105-device-matrix-cli

Conversation

@finalerock44

@finalerock44 finalerock44 commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

… (#1105)

One upload targets N device configs. Each --ios-config : / --android-config :[:play] names exactly one validated cell — no cross-product. A device matrix is single-platform; mixing platforms is rejected before any upload.

  • parseDeviceMatrix() (unit-tested): parsing, :play Google Play cell, mixed- platform + malformed rejection.
  • Each cell validated against the compatibility matrix up front; fails fast naming the bad cell before the flow zip is uploaded.
  • Serialized as the deviceMatrix field; single-device submissions stay byte- identical. targetPlatform now derives from the matrix too.
  • Pre-submit cost preview via POST /uploads/estimateMatrix (cells + est. cost + per-column breakdown); tolerant of older APIs that lack the endpoint (404).
  • --json tests[].device (structured {name, osVersion, googlePlay}) on both the sync and async paths, so a flow run on two devices is disambiguated.

Note: generated schema.types.ts is intentionally not regenerated here (it lags dev's swagger); regenerate from dev after the API lands. Runtime reads config/simulator_name structurally.

What & why

Type of change

  • fix — bug fix
  • feat — new feature
  • perf — performance improvement
  • refactor — code change that's neither a fix nor a feature
  • docs — documentation only
  • chore / ci / build / test — tooling, no user-facing change
  • Breaking change (title has ! or PR notes a BREAKING CHANGE:)

Checklist

  • PR title follows the Conventional Commits format (see comment above)
  • pnpm lint passes
  • pnpm typecheck passes
  • pnpm build passes
  • I have not bumped the version or edited CHANGELOG.md (release-please handles this)
  • I have signed the CLA (the bot will prompt on first contribution)
  • Docs / README.md / STYLE_GUIDE.md updated if behaviour or output changed

How to test


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

… (#1105)

One upload targets N device configs. Each --ios-config <device>:<version> /
--android-config <device>:<apiLevel>[:play] names exactly one validated cell —
no cross-product. A device matrix is single-platform; mixing platforms is
rejected before any upload.

- parseDeviceMatrix() (unit-tested): parsing, :play Google Play cell, mixed-
  platform + malformed rejection.
- Each cell validated against the compatibility matrix up front; fails fast
  naming the bad cell before the flow zip is uploaded.
- Serialized as the deviceMatrix field; single-device submissions stay byte-
  identical. targetPlatform now derives from the matrix too.
- Pre-submit cost preview via POST /uploads/estimateMatrix (cells + est. cost +
  per-column breakdown); tolerant of older APIs that lack the endpoint (404).
- --json tests[].device (structured {name, osVersion, googlePlay}) on both the
  sync and async paths, so a flow run on two devices is disambiguated.

Note: generated schema.types.ts is intentionally not regenerated here (it lags
dev's swagger); regenerate from dev after the API lands. Runtime reads
config/simulator_name structurally.
@finalerock44 finalerock44 self-assigned this Jul 10, 2026
Comment thread test/integration/cloud.integration.test.ts Fixed
The cost preview is best-effort, but the gateway only treated 404 as
'endpoint absent' and threw on 405. An API that predates the endpoint (incl.
the CI Prism mock running against dev's swagger before this lands) 405s with
NO_METHOD_MATCHED, which blocked the submit. Treat 404 and 405 alike — return
null and proceed without a preview. A 400 (invalid config) still surfaces.
CodeQL flags every `exec(\)` in the integration suite as
js/shell-command-injection-from-environment — the built CLI's absolute path
(path.resolve) flows through a template string into a shell. There is no real
injection (test harness, local fixture paths), but the whole class is avoidable.

Route the shared exec helper through execFile(process.execPath, argv) — no
shell — by tokenising the `${CLI} <args>` command. This is CodeQL's
recommended remediation (argument list, not a shell string) and clears the
entire class across all five integration files at once, with no call-site
changes (signature-compatible; runExpectingFailure still reads stdout/stderr
from the rejection). Verified the CLI runs and non-zero exits still surface
stderr.
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