From 55be713cdcfb7946e91eaba0925acaba061fab09 Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 15:01:32 +0300 Subject: [PATCH 1/6] Finalize CHANGELOG for 1.0.0-Beta1 release Rename [Unreleased] to [1.0.0-Beta1] - 2026-05-17, add empty [Unreleased] section, add compare-link, restructure Added section by area, and backfill items audited against git log: - Added: enum DSL (#162), CC support (#164), JavaPreferences default (#167), lint detectors (#141, #176, #181), Detekt rules (#142), FlagRegistry codegen (#110), AGP Variant ProGuard auto-wire, E2E test, R8 DCE module (#165), SECURITY.md (#173), GH templates (#175). - Changed: AGP 9.1 / Gradle 9.3 migration (#135), providers/ directory reshuffle (#128). - Removed: BCV plugin (#150), @LocalFlag/@RemoteFlag. - Fixed: Firebase wrap RuntimeException (#151), MIT POM (#174), quickstart artifact IDs (#179). Closes #166. --- CHANGELOG.md | 83 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 395ca24..8a883e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,38 +7,81 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.0.0-Beta1] - 2026-05-17 + ### Added -- Configuration Cache support (Gradle 9+, AGP 9+) for `featured-gradle-plugin` -- `NSUserDefaultsConfigValueProvider` for iOS/macOS local storage (#104) +#### Core library + +- Core KMP library: `ConfigParam`, `ConfigValue`, `ConfigValues` with reactive `Flow` API +- Explicit initialization mechanism for `ConfigValues` (#98) - `clear()` method on `LocalConfigValueProvider` interface (#101) - Graceful error handling when a provider fails (#100) - Multivariate flag support — `enum` and sealed class `ConfigParam` types (#99) -- Explicit initialization mechanism for `ConfigValues` (#98) +- SKIE 0.10.5 bridge for Swift interop (coroutines, sealed classes, default arguments) +- Combine `Publisher` support in `FeatureFlags.swift` (#88) +- XCFramework published as Swift Package Manager artifact (#91) + +#### Providers + +- `InMemoryConfigValueProvider` — built-in in-memory local provider +- `SharedPreferencesConfigValueProvider` — local storage via SharedPreferences +- `DataStoreConfigValueProvider` — local storage via Jetpack DataStore +- `JavaPreferencesConfigValueProvider` — default JVM local provider (#167, #178) +- `NSUserDefaultsConfigValueProvider` for iOS/macOS local storage (#104) +- `FirebaseConfigValueProvider` — remote config via Firebase Remote Config + +#### Gradle plugin and code generation + +- `featured-gradle-plugin` module — code generation for Kotlin, iOS, and ProGuard (#72, #76, #80, #83, #86) +- Declare flags via Gradle DSL; auto-generate typed extensions and per-function R8 rules +- Enum-typed flags in Gradle DSL (#162) +- Auto-generated `FlagRegistry` initializers per module (#110) +- Auto-wired ProGuard rules into Android builds via AGP Variant API +- Configuration Cache support (Gradle 9+, AGP 9+) (#164) +- E2E integration test for `featured-gradle-plugin` +- `featured-shrinker-tests` — R8 dead-code-elimination verification module (#165) + +#### Static analysis + +- `featured-lint-rules` Android Lint module with `HardcodedFlagValue`, `UncheckedFlagAccess`, `ExpiredFeatureFlag`, and `InvalidFlagReference` detectors (#141, #176, #181) +- Detekt rules: `@BehindFlag` / `@AssumesFlag` annotations and `InvalidFlagReference` / `UncheckedFlagAccess` rules (#142) + +#### Compose and tooling + +- `featured-compose` module — `LocalConfigValues` CompositionLocal and `collectAsState` (#73, #78) +- `featured-debug-ui` module — Compose Multiplatform flag override UI (#79) +- `featured-registry` module — declarative flag scanning across modules (#74) - `featured-testing` module with `FakeConfigValues` and test DSL (#97) -- MkDocs Material documentation website (#96) + +#### Packaging and docs + - Bill of Materials (`featured-bom`) module (#82) - Maven Central publishing for all modules (#81) -- `featured-debug-ui` module — Compose Multiplatform flag override UI (#79, #648f38e) -- `featured-gradle-plugin` module — code generation for Kotlin, iOS, and ProGuard (#72, #76, #80, #83, #86) -- `featured-registry` module — declarative flag scanning across modules (#74) -- `featured-compose` module — `LocalConfigValues` CompositionLocal and `collectAsState` (#73, #78) -- XCFramework published as Swift Package Manager artifact (#91) -- Combine `Publisher` support in `FeatureFlags.swift` (#88) - Dokka API reference generation (#92) -- `FirebaseConfigValueProvider` — remote config via Firebase Remote Config -- `DataStoreConfigValueProvider` — local storage via Jetpack DataStore -- `SharedPreferencesConfigValueProvider` — local storage via SharedPreferences -- `InMemoryConfigValueProvider` — built-in in-memory local provider -- Core KMP library: `ConfigParam`, `ConfigValue`, `ConfigValues` with reactive `Flow` API -- SKIE 0.10.5 bridge for Swift interop (coroutines, sealed classes, default arguments) -- Binary Compatibility Validator (BCV) API dump for all modules (#95) +- MkDocs Material documentation website (#96) - DI pattern documentation for multi-module `ConfigValues` usage (#93) +- `SECURITY.md` with vulnerability disclosure policy (#173) +- GitHub issue templates and pull-request template (#175) + +### Changed + +- Migrated to AGP 9.1.0 + Gradle 9.3.1 with full KMP plugin support (#135) +- Moved all provider modules under `providers/` directory (#128) + +### Removed + +- `binary-compatibility-validator` (BCV) plugin from all modules (#150) +- `@LocalFlag` / `@RemoteFlag` annotations from public API ### Fixed -- `ConfigValues.observe()` not reacting to remote provider changes (#c0e0557) -- Xcode build: JAVA_HOME, FRAMEWORK_SEARCH_PATHS, and Swift module import (#1c488ca) +- `ConfigValues.observe()` not reacting to remote provider changes +- Xcode build: `JAVA_HOME`, `FRAMEWORK_SEARCH_PATHS`, and Swift module import - `@MainActor` and `Sendable` conformance in `FeatureFlags.swift` (#85) +- `FirebaseConfigValueProvider.fetch()` now wraps `RuntimeException` in `FetchException` (#151) +- License mismatch: use MIT in all POM declarations (#174) +- Stale artifact IDs in quick-start docs (#179) -[Unreleased]: https://github.com/androidbroadcast/Featured/compare/HEAD...HEAD +[Unreleased]: https://github.com/androidbroadcast/Featured/compare/v1.0.0-Beta1...HEAD +[1.0.0-Beta1]: https://github.com/androidbroadcast/Featured/releases/tag/v1.0.0-Beta1 From b585203f203a85debd96b645e189b662bc7d61bc Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 15:26:10 +0300 Subject: [PATCH 2/6] Bump VERSION_NAME to 1.0.0-Beta1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release commit for the first Beta of v1.0.0. The publish.yml workflow consumes the tag (v1.0.0-Beta1) as the published version, but ORG_GRADLE_PROJECT_VERSION_NAME falls back to VERSION_NAME for SNAPSHOT pushes — bumping the baseline keeps post-release SNAPSHOT builds on a meaningful track. Refs #156. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7ddc139..c4166f5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,7 +36,7 @@ android.r8.strictInputValidation=true android.proguard.failOnMissingFiles=true # Publishing -VERSION_NAME=0.1.0-SNAPSHOT +VERSION_NAME=1.0.0-Beta1 # Dokka org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled From 51739156d0174596da9755d36f265804c707765c Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 16:09:44 +0300 Subject: [PATCH 3/6] Switch Maven Central publishing to Central Portal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Central Portal (central.sonatype.com) replaced the legacy OSSRH flow; vanniktech 0.36 exposes `publishToMavenCentral` (manual promotion) and `publishAndReleaseToMavenCentral` (auto). The former matches our release process: tag push uploads a bundle to staging, then a human reviews and clicks Publish in the Central Portal UI. - publish.yml: invoke `publishToMavenCentral` instead of the legacy `publishAllPublicationsToMavenCentralRepository`. No build.gradle.kts changes needed: vanniktech 0.36 removed the SonatypeHost parameter — Central Portal is the only API path. CI secrets must be Central Portal User Tokens (central.sonatype.com → Account → Generate User Token), stored as MAVEN_CENTRAL_USERNAME and MAVEN_CENTRAL_PASSWORD. Refs #156. --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f7a61e5..a5714cc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -46,7 +46,9 @@ jobs: ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.GPG_KEY_ID }} ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_KEY_PASSWORD }} ORG_GRADLE_PROJECT_VERSION_NAME: ${{ steps.version.outputs.VERSION_NAME }} - run: ./gradlew --no-daemon publishAllPublicationsToMavenCentralRepository + # publishToMavenCentral = manual promotion (no auto-release); --no-configuration-cache for + # release-pipeline debuggability (runs once per tag, CC savings are zero). + run: ./gradlew --no-daemon publishToMavenCentral --no-configuration-cache publish-xcframework: name: Publish XCFramework to GitHub Release From d6b33822de4d090e07d90fe231fe3e93e2923b27 Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 16:14:57 +0300 Subject: [PATCH 4/6] Add featured-lint-rules and featured-testing to BOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both modules publish to Maven Central but were missing from the featured-bom constraints — consumers had to pin their versions manually. Adding them restores the BOM contract: every published Featured artifact is version-managed through featured-bom. Refs #156. --- featured-bom/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/featured-bom/build.gradle.kts b/featured-bom/build.gradle.kts index c6a4e69..9bd2fff 100644 --- a/featured-bom/build.gradle.kts +++ b/featured-bom/build.gradle.kts @@ -20,7 +20,9 @@ dependencies { api(project(":featured-compose")) api(project(":featured-registry")) api(project(":featured-debug-ui")) + api(project(":featured-testing")) api(project(":featured-gradle-plugin")) + api(project(":featured-lint-rules")) api(project(":featured-platform")) api(project(":featured-detekt-rules")) From 993ec6e4aec30984d787a872ace059d8019077cf Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 16:15:45 +0300 Subject: [PATCH 5/6] Expose ConfigParam.description as .summary in Swift via @ObjCName MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConfigParam.description collides with the inherited NSObject.description() ObjC selector, so SKIE was forced to rename the property to description_ in the generated Swift API — an ugly first-impression name for the 1.0.0-Beta1 release. Annotating the Kotlin property with @ObjCName("summary") gives Swift consumers a clean ConfigParam.summary while keeping the Kotlin API untouched (description remains the canonical name on JVM/JS targets). Refs #156. --- CHANGELOG.md | 1 + .../kotlin/dev/androidbroadcast/featured/ConfigParam.kt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a883e0..3cf566c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Swift API: `ConfigParam.description` is now exposed as `.summary` (via `@ObjCName`), avoiding the SKIE-generated `description_` workaround for the `NSObject.description()` collision - `ConfigValues.observe()` not reacting to remote provider changes - Xcode build: `JAVA_HOME`, `FRAMEWORK_SEARCH_PATHS`, and Swift module import - `@MainActor` and `Sendable` conformance in `FeatureFlags.swift` (#85) diff --git a/core/src/commonMain/kotlin/dev/androidbroadcast/featured/ConfigParam.kt b/core/src/commonMain/kotlin/dev/androidbroadcast/featured/ConfigParam.kt index 10d709e..6a465af 100644 --- a/core/src/commonMain/kotlin/dev/androidbroadcast/featured/ConfigParam.kt +++ b/core/src/commonMain/kotlin/dev/androidbroadcast/featured/ConfigParam.kt @@ -1,7 +1,9 @@ @file:Suppress("unused") +@file:OptIn(kotlin.experimental.ExperimentalObjCName::class) package dev.androidbroadcast.featured +import kotlin.native.ObjCName import kotlin.reflect.KClass /** @@ -44,6 +46,7 @@ public class ConfigParam * An optional description for the configuration parameter. * This can be used to provide additional context or information about the parameter. */ + @property:ObjCName("summary") public val description: String? = null, /** * Category or group name for organizing related parameters. From 64da89fe93c84ab2ed1e95ebd015c5582d1d1b5e Mon Sep 17 00:00:00 2001 From: kirich1409 Date: Sun, 17 May 2026 17:07:17 +0300 Subject: [PATCH 6/6] Address review: align CHANGELOG with shipped SKIE/Gradle versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copilot review on PR #188 flagged two stale version mentions in the 1.0.0-Beta1 release notes: - SKIE entry said 0.10.5; libs.versions.toml pins 0.10.10 - Gradle migration entry said 9.3.1; wrapper now ships 9.4.1 (post-#135 dependabot bump) Release notes must match the artifacts users get when checking out the v1.0.0-Beta1 tag — bumping both to actual. --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf566c..f8aea62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `clear()` method on `LocalConfigValueProvider` interface (#101) - Graceful error handling when a provider fails (#100) - Multivariate flag support — `enum` and sealed class `ConfigParam` types (#99) -- SKIE 0.10.5 bridge for Swift interop (coroutines, sealed classes, default arguments) +- SKIE 0.10.10 bridge for Swift interop (coroutines, sealed classes, default arguments) - Combine `Publisher` support in `FeatureFlags.swift` (#88) - XCFramework published as Swift Package Manager artifact (#91) @@ -66,7 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Migrated to AGP 9.1.0 + Gradle 9.3.1 with full KMP plugin support (#135) +- Migrated to AGP 9.1.0 + Gradle 9.4.1 with full KMP plugin support (#135) - Moved all provider modules under `providers/` directory (#128) ### Removed