Skip to content

Commit 45f8aed

Browse files
authored
Merge pull request #1 from nomasystems/release/0.9.0
Release 0.9.0
2 parents 588f2ba + c05d696 commit 45f8aed

529 files changed

Lines changed: 69152 additions & 12579 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,35 @@ concurrency:
1313

1414
jobs:
1515
analyze-and-test:
16-
name: Analyze + test (Flutter ${{ matrix.flutter }})
17-
# GitHub-hosted Ubuntu. Self-hosted runners are blocked for public repos
18-
# by default at the org level (security: anyone can submit PRs).
19-
# GitHub-hosted is free + unlimited for public OSS repos.
20-
runs-on: ubuntu-latest
21-
timeout-minutes: 20
16+
name: Analyze + test (Flutter ${{ matrix.flutter }} / ${{ matrix.os }})
17+
# `ubuntu-latest` is the primary gate. `macos-latest` is added so we
18+
# exercise the iOS / macOS pod / `image_picker` / `record` /
19+
# `image_cropper` host-side codegen at least once per push — without
20+
# this, breakage in those plugins only surfaces when a real iOS dev
21+
# opens the example.
22+
runs-on: ${{ matrix.os }}
23+
timeout-minutes: 25
2224
strategy:
2325
fail-fast: false
2426
matrix:
25-
# Pin to a stable channel; bump explicitly when the package's
26-
# `environment.sdk` constraint is widened.
27+
os: [ubuntu-latest, macos-latest]
2728
flutter: ["3.x"]
29+
channel: [stable]
30+
include:
31+
# Informational job: track the next release channel so we get
32+
# an early warning when the upcoming Flutter release breaks
33+
# something. Failures here do not fail the workflow.
34+
- os: ubuntu-latest
35+
flutter: any
36+
channel: beta
37+
experimental: true
38+
continue-on-error: ${{ matrix.experimental == true }}
2839
steps:
2940
- uses: actions/checkout@v5
3041

3142
- uses: subosito/flutter-action@v2
3243
with:
33-
channel: stable
44+
channel: ${{ matrix.channel }}
3445
flutter-version: ${{ matrix.flutter }}
3546

3647
- name: Flutter version
@@ -46,15 +57,81 @@ jobs:
4657
run: flutter analyze --fatal-infos --fatal-warnings
4758

4859
- name: Tests + coverage
49-
run: flutter test --coverage
60+
# Golden baselines are generated on Linux (see regen-goldens.yml).
61+
# macOS renders text/anti-aliasing differently, so the same PNGs
62+
# never match there — exclude the golden tag on macOS only. Linux
63+
# still runs (and gates) the full suite including goldens.
64+
run: flutter test --coverage ${{ matrix.os == 'macos-latest' && '-x golden' || '' }}
5065

5166
- name: Coverage gate (≥80%)
67+
# Only the Linux/stable job gates coverage: it runs the full suite
68+
# (goldens included) so its lcov is the complete picture. macOS
69+
# excludes goldens, so its coverage is intentionally lower.
70+
if: matrix.os == 'ubuntu-latest' && matrix.channel == 'stable'
5271
run: |
5372
awk 'BEGIN{lh=0; lf=0} /^LF:/{sub("LF:",""); lf+=$1} /^LH:/{sub("LH:",""); lh+=$1} END{ pct=(lh/lf)*100; printf "Coverage: %d/%d = %.2f%%\n", lh, lf, pct; if (pct < 80.0) { print "FAIL: coverage below 80% threshold"; exit 1 } }' coverage/lcov.info
5473
74+
# Upload coverage to Codecov on every successful run. The badge in
75+
# README.md (https://codecov.io/gh/nomasystems/noma_chat_flutter)
76+
# picks this up automatically. Requires the repo to be linked at
77+
# codecov.io; public repos don't need a token. Only the ubuntu-latest
78+
# / stable job uploads — running it from every matrix combo
79+
# would create duplicate reports.
80+
- name: Upload coverage to Codecov
81+
uses: codecov/codecov-action@v4
82+
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.os == 'ubuntu-latest' && matrix.channel == 'stable'
83+
with:
84+
files: ./coverage/lcov.info
85+
fail_ci_if_error: false
86+
5587
- name: Dartdoc dry-run
5688
run: dart doc --dry-run
5789

90+
example:
91+
name: Example app compiles
92+
runs-on: ubuntu-latest
93+
timeout-minutes: 15
94+
steps:
95+
- uses: actions/checkout@v5
96+
97+
- uses: subosito/flutter-action@v2
98+
with:
99+
channel: stable
100+
flutter-version: "3.x"
101+
102+
- name: Pub get (package)
103+
run: flutter pub get
104+
105+
- name: Pub get (example)
106+
working-directory: example
107+
run: flutter pub get
108+
109+
- name: Analyze example
110+
working-directory: example
111+
run: flutter analyze --fatal-infos --fatal-warnings
112+
113+
- name: Test example
114+
working-directory: example
115+
run: flutter test
116+
117+
performance:
118+
name: Performance regression gate
119+
runs-on: ubuntu-latest
120+
timeout-minutes: 10
121+
steps:
122+
- uses: actions/checkout@v5
123+
124+
- uses: subosito/flutter-action@v2
125+
with:
126+
channel: stable
127+
flutter-version: "3.x"
128+
129+
- name: Install dependencies
130+
run: flutter pub get
131+
132+
- name: Performance test (10k messages ≤ 8s)
133+
run: flutter test test/cache/hive_chat_datasource_performance_test.dart --reporter=expanded
134+
58135
pana:
59136
name: pub.dev score (pana)
60137
runs-on: ubuntu-latest
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: regen-goldens
2+
3+
# Regenerates the golden baselines on Linux — the same OS that validates
4+
# them in `ci.yml` and `publish.yml` — and uploads them as an artifact so a
5+
# maintainer can download + commit the CI-matched PNGs. This solves the
6+
# local (macOS) vs CI (Linux) pixel-diff mismatch: goldens generated on a
7+
# developer's Mac never match the Linux runner's text rendering.
8+
#
9+
# Usage:
10+
# 1. Push the release branch (this runs automatically) or trigger manually.
11+
# 2. Download the `goldens` artifact from the run.
12+
# 3. Replace test/golden/goldens/ with its contents, commit, push.
13+
#
14+
# Uses `channel: stable` with no version pin to mirror `publish.yml` exactly,
15+
# so the regenerated baselines match the runner that gates publishing.
16+
17+
on:
18+
workflow_dispatch:
19+
push:
20+
branches:
21+
- "release/**"
22+
23+
jobs:
24+
regen:
25+
name: Regenerate golden baselines (Linux)
26+
runs-on: ubuntu-latest
27+
timeout-minutes: 20
28+
steps:
29+
- uses: actions/checkout@v5
30+
31+
- uses: subosito/flutter-action@v2
32+
with:
33+
channel: stable
34+
35+
- name: Flutter version
36+
run: flutter --version
37+
38+
- name: Install dependencies
39+
run: flutter pub get
40+
41+
- name: Regenerate goldens
42+
run: flutter test --update-goldens test/golden/
43+
44+
- name: Upload regenerated goldens
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: goldens
48+
path: test/golden/goldens/
49+
if-no-files-found: error
50+
retention-days: 3

.pubignore

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
11
# Files / directories excluded from the tarball uploaded to pub.dev.
2-
# This is on top of pub's own default ignores (.git/, .dart_tool/, build/, …).
3-
# Anything excluded here is still kept in the GitHub repo; we only trim
4-
# what consumers don't need.
2+
#
3+
# IMPORTANT: when a .pubignore exists, pub uses it INSTEAD of .gitignore
4+
# (they are not merged). So every build/dev artefact that .gitignore keeps
5+
# out of the repo must ALSO be listed here, or it leaks into the published
6+
# tarball. Pub only hard-ignores .git/ and .dart_tool/ on its own — notably
7+
# NOT root build/, so the 70 MB test_cache .dill shipped until this list
8+
# grew. Anything excluded here is still kept in the GitHub repo; we only
9+
# trim what consumers don't need.
10+
11+
# Build / cache artefacts (regenerated on demand; never useful to consumers).
12+
build/
13+
**/build/
14+
.dart_tool/
15+
**/.dart_tool/
16+
17+
# Coverage reports and stray run logs.
18+
coverage/
19+
.coverage/
20+
*.log
21+
22+
# IDE / editor / OS noise.
23+
.idea/
24+
.vscode/
25+
*.iml
26+
.DS_Store
27+
28+
# Example platform host projects — pub.dev renders example/lib, consumers
29+
# never need the iOS/Android Runner scaffolding. Kept in the repo.
30+
example/ios/
31+
example/android/
532

633
# Tests are useful in the repo but not for consumers; they would bloat the
734
# tarball by megabytes and pub.dev does not render them anywhere.

ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Distinguishes real DMs from conceptual groups with 2 participants (e.g. a plan w
168168
- Optional `logger` in `ChatConfig`, propagated to `BearerAuthInterceptor` and the 4 main APIs (users, rooms, messages, contacts).
169169
- 11 `catch (_)` cache-best-effort sites replaced with `catch (e) { _logger?.call('warn', '...: $e'); }`.
170170
- `_openBoxSafe()` recovery logs + metrics `box_delete_failed` / `box_reopen_failed`.
171-
- Exported `MetricCallback`: `cache_hit`, `cache_miss`, `cache_eviction`, `cache_ttl_expired`.
171+
- `MetricCallback` (typedef `void Function(String metric, Map<String, dynamic> data)`) exported from `package:noma_chat/noma_chat_advanced.dart`. Events emitted today: `cache_hit`, `cache_miss`, `cache_stale_fallback`, `cache_eviction`, `cache_ttl_expired`, `box_corrupted`, `box_delete_failed`, `box_reopen_failed`, `schema_migration_wipe`.
172172

173173
## Backend integration
174174

0 commit comments

Comments
 (0)