Skip to content

ci: release guard + SDK staleness check + 100% lib test coverage gate - #18

Merged
KAMRONBEK merged 3 commits into
mainfrom
ci/release-guard-and-sdk-staleness
Jul 26, 2026
Merged

KAMRONBEK merged 3 commits into
mainfrom
ci/release-guard-and-sdk-staleness

Conversation

@KAMRONBEK

@KAMRONBEK KAMRONBEK commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes the two remaining CI-tooling items from the review roadmap, plus raises the library to full test coverage and gates it in CI. Independent, locally-validated additions.

1. Tarball guard before publish (ddda5e3)

internal/module_scripts/verify-pack.js runs in release.yml immediately before npm publish. It parses npm pack --dry-run --json and fails the release if:

  • a required file is missing (README, CHANGELOG, LICENSE/NOTICE, build/, plugin/build/, podspec, MyIdModule.swift, android/build.gradle, MyIdModule.kt), or
  • a forbidden path would ship (^src/, ^plugin/src/, example/, __tests__/, *.test/spec, .env, node_modules/, *.tsbuildinfo).

android/src/ is intentionally allowed (autolinked native sources). A published npm version can't be overwritten, so this is the cheapest place to catch a bad manifest.

Validated locally: passes on the current tarball (36 files, 14/14 required, 0 forbidden); matcher unit-tested against allow/block cases including the android/src/ false-positive edge.

2. Weekly SDK staleness check (23f5037)

New sdk-staleness.yml (weekly cron + manual workflow_dispatch) runs check-sdk-staleness.js:

  • reads the pins from the repo (ios/MyId.podspec, android/build.gradle) so it can't itself go stale,
  • fetches latest stable from the CocoaPods trunk API (iOS) and Artifactory maven-metadata.xml (Android),
  • ignores pre-releases — Artifactory lists <latest>/<release> as 3.1.10-beta02 while the newest stable is 3.1.9; a naive check would false-alarm every run,
  • on drift, opens or updates a single tracking issue (deduped by title); posts a status line to the run summary either way.

Validated locally: correctly reports iOS 3.1.3 and Android 3.1.9 both up-to-date (beta ignored); version-compare unit-tested (3.1.10 > 3.1.9, 2.4.91 > 2.4.9, beta filtering).

Neither script is shipped in the npm tarball (internal/ isn't in files — and the new tarball guard would catch it if it were).

3. Full library test coverage + CI gate (deec84c)

Raises coverage of the shippable lib (src + plugin/src) and the two scripts above from ~76% to 100% statements/branches/functions/lines, and enforces it so it can't regress. 106 tests, 8 suites.

  • New suites: native-module resolution/caching (MyIdModule.ts, was 0%), web fallback (MyIdModule.web.ts, was 0%), and every config-plugin mod body (Android repo injection incl. centralized-skip/warn/.kts-throw paths; iOS frameworks, camera, microphone, firebase, privacy manifest) via a @expo/config-plugins mock. The tarball matcher and version-compare claims from §1–2 are now formalized as real tests.
  • Extended identify() tests: error-path fallbacks, cross-realm isMyIdError re-throw, and an exact-match pin that every optional config field reaches native intact.
  • The two scripts export their pure logic behind a require.main === module guard (CLI behavior unchanged); the genuine network / npm pack / CLI-entry boundary is marked with visible istanbul ignore comments rather than silently excluded.
  • test:ci now runs --coverage; package.json adds scoped collectCoverageFrom, a coverageThreshold ratchet (98/95/100/98), and a testMatch that excludes the script literally named test.js. The checks job enforces the threshold and uploads the coverage report; release.yml inherits the gate.

Validated locally: lint, typecheck, build, build:plugin, and test:ci all pass; 100% on every file; both CLI scripts still run identically.

Note: the coverage floor now also gates release.yml, so a future threshold bump with no code change would block a release — intentional, but worth knowing.

Add internal/module_scripts/verify-pack.js and run it in release.yml right
before `npm publish`. It parses `npm pack --dry-run --json` and fails the
release if a required file (README, CHANGELOG, build output, native manifests)
is missing or if source/tests/secrets/example would leak. A published npm
version can't be overwritten, so this catches a bad tarball before it ships.
New sdk-staleness.yml workflow (weekly + manual dispatch) runs
check-sdk-staleness.js, which compares the pinned MyID SDK versions (read
from ios/MyId.podspec and android/build.gradle) against the newest STABLE
upstream — iOS via the CocoaPods trunk API, Android via the Artifactory
maven-metadata. Pre-releases are ignored on purpose (Artifactory advertises
3.1.10-beta02 as <release> while 3.1.9 is the newest stable). On drift it
opens or updates a single tracking issue.
Raise test coverage of the shippable library (src + plugin/src) and the
two release-critical scripts from ~76% to 100% statements/branches/
functions/lines, and enforce it so it can't regress.

New tests
- src/__tests__/module.test.ts: getNativeMyIdModule() resolution,
  caching, and lazy binding (was 0%).
- src/__tests__/web.test.ts: web fallback throws a typed MyIdError.
- plugin/src/__tests__/plugin-mods.test.ts: drives every config-plugin
  mod body (Android permissions, settings.gradle vs allprojects repo
  injection incl. the centralized-skip, warn, and .kts-throw paths; iOS
  static frameworks, camera default/custom/preserve, microphone,
  firebase workaround, privacy-manifest merge) by mocking
  @expo/config-plugins.
- internal/module_scripts/__tests__/*: tarball required/forbidden
  logic; version compare, pre-release filtering, JSON/XML version
  parsing, stale-decision, emit, and a real-pin regex regression.
- Extended native.test.ts and mock.test.ts with error-path, override,
  cross-realm re-throw, optional-field passthrough, and fake-timer
  branches.

Testability refactors (CLI behavior unchanged)
- verify-pack.js and check-sdk-staleness.js export their pure logic
  behind a require.main === module guard; the genuine network / npm-pack
  / CLI-entry boundary is marked with visible istanbul-ignore comments
  rather than silently excluded from coverage.

CI / config
- test:ci runs with --coverage; package.json adds scoped
  collectCoverageFrom, a coverageThreshold ratchet (98/95/100/98), and a
  testMatch that excludes the script literally named test.js.
- ci.yml checks job enforces the threshold and uploads the coverage
  report as an artifact; release.yml inherits the gate.
- .gitignore ignores coverage/.
@KAMRONBEK KAMRONBEK changed the title ci: release tarball guard + weekly SDK staleness check ci: release guard + SDK staleness check + 100% lib test coverage gate Jul 26, 2026
@KAMRONBEK
KAMRONBEK merged commit 62152f9 into main Jul 26, 2026
5 checks passed
@KAMRONBEK KAMRONBEK mentioned this pull request Jul 26, 2026
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.

1 participant