Skip to content

fix: republish @amritk/mini-lynx-native with its dist, and remove the development export condition #102

fix: republish @amritk/mini-lynx-native with its dist, and remove the development export condition

fix: republish @amritk/mini-lynx-native with its dist, and remove the development export condition #102

Workflow file for this run

name: CI
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Lint
run: bun run check
- name: Check mini reactivity footgun
run: bun run check:reactivity
# Regenerating `llms.txt` catches a stale bundle, but a stale *source*
# regenerates perfectly: an `AI.md` that never mentions the subpath a
# release added is wrong in a way no diff can see. This reads what each
# package actually exports and asks whether its `AI.md` says so.
- name: Check AI docs match what each package publishes
run: bun run check:ai-docs
# `llms.txt` and `llms-full.txt` are generated from the packages' `AI.md`
# files and committed, so they go stale in exactly the way a committed
# build artifact always does: silently, and only for the audience that
# cannot complain. They had drifted far enough to describe a design that
# no longer existed. Regenerating and diffing is the whole guard.
- name: Check generated LLM docs are current
run: |
bun run generate-llms
git diff --exit-code llms.txt llms-full.txt
# Ahead of the type check, not after it. The packages used to resolve each
# other's SOURCE while type-checking, through a `development` condition in
# their exports maps — which meant the manifests shipped a condition
# pointing at `./src/*.ts` inside a tarball that also ships `src`, so
# anything honouring it handed consumers raw TypeScript. The condition is
# gone; cross-package imports resolve to `dist` like a consumer's do, and
# `dist` has to exist by the time anything reads it.
- name: Build
run: bun run build
- name: Type check
run: bun run types:check
# Unaffected by the ordering above: vitest.config.ts aliases every
# workspace package to its `src/`, so the suite has never needed a build.
- name: Test
run: bun run test
# Loads every compiled module under plain Node, drives the built
# mini-lynx runtime end-to-end through its fake Element PAPI, and
# installs packed tarballs like an npm consumer — catches build-, pack-
# and manifest-level corruption the src-aliased tests cannot see.
- name: Smoke and e2e test built artifacts
run: bun run test:dist
# `android` below — and `ios`, while it was enabled — are the only things
# anywhere that compile the native halves of the `@amritk/lynx-*` packages —
# notifications, location, dialogs and deep linking.
# Everything in `Check` above runs in JavaScript and would pass just as
# happily against Kotlin and Objective-C that do not build —
# `src/native-contract.test.ts` narrows that gap by comparing the two native
# method surfaces against the TypeScript one, but comparing signatures is not
# compiling.
#
# They are separate jobs rather than steps because they need toolchains the
# main job has no use for, and a macOS runner costs several times an Ubuntu
# one — keeping them apart means a failure here does not hide a failure there.
android:
name: Android native
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- uses: android-actions/setup-android@v3
# The runner image ships several platforms but the set moves; asking for
# the one `build.gradle.kts` compiles against is cheap and removes a
# failure mode that would look like a code problem.
- name: Install the compile SDK
run: sdkmanager "platforms;android-35" "build-tools;35.0.0"
- uses: gradle/actions/setup-gradle@v4
- name: Install dependencies
run: bun install --frozen-lockfile
# `--require-sdk` turns the "no Android SDK, skipping" path into a
# failure: skipping is right for a contributor's laptop and would be a
# silently green CI job.
- name: Compile the Android libraries
run: bun run check:android --require-sdk
# DISABLED — the iOS job below was the entire wall clock of this workflow:
# 81 minutes, against 2m17s for `Android native` and 50s for `Check`.
#
# Not because the code is large. The four pods are ~2,600 lines of
# Objective-C between them. Each `pod lib lint` builds an eight-target graph
# — `Lynx`, `LynxBase`, `LynxServiceAPI`, `Lynx-LynxResources`, `PrimJS` and
# a generated host `App` — and compiling the Lynx engine is essentially the
# whole twenty minutes per pod. Because every lint gets its own throwaway
# sandbox, that compile happened four times per run, sequentially, to check
# four small files. On a macOS runner's 10x multiplier that is ~810 billed
# minutes for a check whose Android counterpart costs two.
#
# What is lost while this is off: nothing anywhere compiles the Objective-C.
# `src/native-contract.test.ts` still compares the native method surfaces
# against the TypeScript one, so a renamed or dropped method is still caught
# — but a syntax error, a bad selector, or a header that no longer exists
# will reach a published tarball. Treat a release touching
# `packages/lynx-*/ios/**` as unverified and lint those pods by hand:
#
# cd packages/lynx-notifications/ios
# pod lib lint MiniLynxNotifications.podspec --allow-warnings --platforms=ios
#
# Re-enabling as-is brings the 81 minutes back with it. The two fixes worth
# making first, in order of payoff: gate the job on `packages/lynx-*/ios/**`
# and the podspecs changing (use a job-level `if:`, not a workflow-level
# `paths:` — a workflow that never runs never reports, and a required status
# check that never reports blocks the PR forever), and collapse the four
# lints into a single Podfile carrying all four as development pods so Lynx
# compiles once instead of four times.
#
# ios:
# name: iOS native
# runs-on: macos-15
# steps:
# - uses: actions/checkout@v4
#
# # `pod lib lint` builds the podspec's sources against the real iOS SDK,
# # resolving `Lynx` from CocoaPods so the Lynx headers the module imports
# # are the actual ones. It validates from the files on disk and never
# # fetches the podspec's `source`.
# #
# # `--allow-warnings` because CocoaPods warns about things a library
# # published from a monorepo subdirectory cannot avoid; it does NOT
# # suppress compiler errors, which is the point of running this.
# - name: Lint and compile the notifications pod
# working-directory: packages/lynx-notifications/ios
# run: pod lib lint MiniLynxNotifications.podspec --allow-warnings --platforms=ios
#
# # A separate step rather than a second podspec in the same command, so a
# # failure names which pod broke without reading the log.
# - name: Lint and compile the location pod
# working-directory: packages/lynx-location/ios
# run: pod lib lint MiniLynxLocation.podspec --allow-warnings --platforms=ios
#
# - name: Lint and compile the dialogs pod
# working-directory: packages/lynx-dialogs/ios
# run: pod lib lint MiniLynxDialogs.podspec --allow-warnings --platforms=ios
#
# - name: Lint and compile the deep-linking pod
# working-directory: packages/lynx-deep-linking/ios
# run: pod lib lint MiniLynxDeepLinking.podspec --allow-warnings --platforms=ios