From 38dc8162d0f031abc1a091e5cc0cf52db6db3893 Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sat, 30 May 2026 22:45:45 +0300 Subject: [PATCH 1/2] Prepare 1.0.0 release: version, changelog, README stability, fix BCV docs --- CHANGELOG.md | 13 ++++++++++--- CLAUDE.md | 2 +- CONTRIBUTING.md | 3 +-- README.md | 10 ++++++++++ gradle.properties | 2 +- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da4260b..e1ea18f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.0.0] - 2026-05-30 ### Removed @@ -31,13 +31,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New `dev.androidbroadcast.featured.application` Gradle plugin: aggregates `featured-manifest.json` artifacts from project dependencies declared via `featuredAggregation(project(...))` and generates `object GeneratedFeaturedRegistry { val all: List> }` in `build/generated/featured/commonMain/`. Apply alongside `dev.androidbroadcast.featured` in the application module; wire the output directory into your source set manually (e.g., `kotlin.sourceSets.commonMain.kotlin.srcDir(...)`). Modules declaring `enum` flags also require a regular `implementation(project(...))` dependency in the consumer so the enum class is on the compile classpath; primitive-only modules need only `featuredAggregation(...)`. - Three KMP sample feature modules — `:sample:feature-checkout`, `:sample:feature-promotions`, `:sample:feature-ui` — each declaring its own flags via the `featured { ... }` DSL. Serves as the canonical multi-module reference. - `EnumDropdown` component in `featured-debug-ui` for overriding `enum`-typed flags in `FeatureFlagsDebugScreen`; `ConfigParam` now carries `enumConstants: List?` populated by codegen so the debug UI can render the dropdown without reflection. -- `featured-gradle-plugin` extracted to a `build-logic/` included build; `pluginManagement { includeBuild("build-logic") }` in the root `settings.gradle.kts` exposes it to all main-build subprojects without a version coordinate. +- `featured-gradle-plugin` lives at the repo root as an included build; `pluginManagement { includeBuild("featured-gradle-plugin") }` in the root `settings.gradle.kts` exposes it to all main-build subprojects without a version coordinate. ### Fixed - Restored R8 per-function DCE: ProGuard `-assumevalues` rules now target the actual Kotlin-compiled class name (`GeneratedFlagExtensionsXKt`). The rules were silently no-op since `@file:JvmName` was removed in an earlier PR; unused boolean flags are once again eliminated at shrinking time. - iOS framework can now `export(project(":sample:feature-*"))` without the K/N `ObjCExportCodeGenerator` crashing — requires `api(project(...))` linkage in the aggregator module so K/N has access to type adapters for generic `ConfigParam` specializations. +### Platform stability + +- **Android — Stable.** Public API and behavior are covered by SemVer. +- **iOS (SKIE / Swift DCE) — Preview.** Functional, but the Swift-facing API and the SPM packaging may change in minor releases without a major bump. +- **JVM — Preview.** Functional, but the API may change in minor releases without a major bump. + ## [1.0.0-Beta1] - 2026-05-17 ### Added @@ -115,5 +121,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - License mismatch: use MIT in all POM declarations (#174) - Stale artifact IDs in quick-start docs (#179) -[Unreleased]: https://github.com/androidbroadcast/Featured/compare/v1.0.0-Beta1...HEAD +[Unreleased]: https://github.com/androidbroadcast/Featured/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/androidbroadcast/Featured/compare/v1.0.0-Beta1...v1.0.0 [1.0.0-Beta1]: https://github.com/androidbroadcast/Featured/releases/tag/v1.0.0-Beta1 diff --git a/CLAUDE.md b/CLAUDE.md index 1bbdbd0..e787fba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -106,7 +106,7 @@ For non-reactive reads (logging, eager-conditional paths) use `configValues.getV - **Explicit API mode** is on for every KMP module — all public declarations need explicit visibility. Generated flag objects are deliberately `internal`. - **Version catalog** (`gradle/libs.versions.toml`) is the single source of truth for dependency versions. - **Spotless / ktlint** runs over `**/*.kt` and `**/*.kts` excluding `build/`. CI fails on `spotlessCheck`. -- **Binary Compatibility Validator** enforces public-API stability — a public-surface change without `apiDump` update fails CI. Featured has **no migration window** for breaking changes; breaking changes go in directly, the version number reflects it. +- **Public-API stability is reviewed manually in PRs** — there is no automated Binary Compatibility Validator gate (BCV was removed in #150). Reviewers check public-surface changes by hand. Featured has **no migration window** for breaking changes; breaking changes go in directly, the version number reflects it. - **Branching:** `develop` is the integration branch; PRs go to `develop`, not `main`. `main` is updated only on releases. One logical change per PR — do not bundle. - **Comment language:** English (per `.github/copilot-instructions.md`). - **iOS:** SKIE is applied in `:core`; the XCFramework is named `FeaturedCore`. SKIE config is `skie.toml` at repo root. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08212cf..fb910a7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,8 +63,7 @@ Featured follows [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH` - Changing a function signature in a way that requires call-site updates - Changing the behavior of an existing API in a way that requires migration -Binary Compatibility Validator (BCV) enforces this automatically — a CI check will fail if -a public API surface changes without an explicit `apiDump` update. +Public API changes are reviewed manually during code review — there is no automated Binary Compatibility Validator gate. Reviewers verify that any public-surface change is intentional and that the version bump reflects it. ## Deprecation Policy diff --git a/README.md b/README.md index 7147969..229d120 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,16 @@ Featured is a type-safe, reactive feature-flag and configuration management libr - **Multiple providers** — DataStore, SharedPreferences, NSUserDefaults, JavaPreferences, Firebase Remote Config, ConfigCat, or a custom one. - **Debug UI** — a ready-made Compose screen for overriding flags at runtime. +## Platform stability + +| Platform | Status | +|---|---| +| Android | **Stable** | +| iOS (SKIE / DCE) | **Preview** | +| JVM | **Preview** | + +*Preview* means the platform is functional but its public API may change in minor releases without a major version bump. *Stable* platforms follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + ## Quick example ```kotlin diff --git a/gradle.properties b/gradle.properties index c4166f5..8baa471 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,7 +36,7 @@ android.r8.strictInputValidation=true android.proguard.failOnMissingFiles=true # Publishing -VERSION_NAME=1.0.0-Beta1 +VERSION_NAME=1.0.0 # Dokka org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled From dac0d6aa7d84f048e6ff346d8dca0ca72f4f89b2 Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sat, 30 May 2026 23:10:15 +0300 Subject: [PATCH 2/2] Fill CHANGELOG gaps (#196 #193 #190) and correct deprecation-policy docs --- CHANGELOG.md | 3 +++ CONTRIBUTING.md | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ea18f..fbbfb2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `ExtensionFunctionGenerator` emits non-suspend `is*Enabled()` / `get*()` extension functions — they delegate to `getValueCached` and can be called from any context without a coroutine. Callers that previously wrapped them in `runBlocking { … }` or a coroutine scope can drop the wrapper. - `ConfigValues.resetOverride` re-resolves the effective value synchronously through the full provider priority chain; [getValueCached] reflects the updated value immediately after the call returns. - Generated `GeneratedLocalFlagsX` / `GeneratedRemoteFlagsX` objects are now `internal` to their declaring Gradle module — each feature module's flag declarations are an implementation detail and no longer leak across module boundaries. Cross-module flag introspection (e.g. the debug screen) flows exclusively through `GeneratedFeaturedRegistry.all`, which the aggregator plugin builds from per-module manifests. The sample app demonstrates the per-module wiring pattern: one `ConfigValues` per feature module plus a dedicated debug aggregator, all sharing the same `LocalConfigValueProvider`. +- The plugin's ProGuard-rules generation task is renamed from `generateProguardRules` to `generateFeaturedProguardRules` to avoid name collisions with other plugins. (#190) +- User documentation moved from the in-repo MkDocs site to the [GitHub Wiki](https://github.com/AndroidBroadcast/Featured/wiki); the `docs/` site and `mkdocs.yml` are removed from the repository. (#193) ### Added @@ -35,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `ConfigValues.observe()` now wraps provider `Flow` collection in `catch` — exceptions thrown by a local or remote provider are routed to `onProviderError` instead of propagating and breaking the observation flow. (#196) - Restored R8 per-function DCE: ProGuard `-assumevalues` rules now target the actual Kotlin-compiled class name (`GeneratedFlagExtensionsXKt`). The rules were silently no-op since `@file:JvmName` was removed in an earlier PR; unused boolean flags are once again eliminated at shrinking time. - iOS framework can now `export(project(":sample:feature-*"))` without the K/N `ObjCExportCodeGenerator` crashing — requires `api(project(...))` linkage in the aggregator module so K/N has access to type adapters for generic `ConfigParam` specializations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb910a7..669b21a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,13 +65,12 @@ Featured follows [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH` Public API changes are reviewed manually during code review — there is no automated Binary Compatibility Validator gate. Reviewers verify that any public-surface change is intentional and that the version bump reflects it. -## Deprecation Policy +## API Stability and Breaking Changes -1. An API is marked `@Deprecated` with a `ReplaceWith` suggestion and a `DeprecationLevel.WARNING`. -2. The deprecated API is kept for **at least one minor release** before being promoted to `ERROR` level. -3. APIs at `ERROR` level are removed in the **next major release**. +Featured has **no deprecation or migration window**. Breaking changes are made directly; the version number reflects the impact per the Versioning table above. -Example timeline: deprecated in `1.2.0` → error in `1.3.0` → removed in `2.0.0`. +- **Android (Stable):** a breaking public-API change (removed/renamed symbol, changed signature) requires a `MAJOR` version bump. +- **iOS (Preview) and JVM (Preview):** public API may change in `MINOR` releases without a major bump; no migration window is provided. ## Releasing a New Version