Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
84 changes: 64 additions & 20 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,82 @@ 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.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)

#### 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.4.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)
- 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)
- `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
Original file line number Diff line number Diff line change
@@ -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

/**
Expand Down Expand Up @@ -44,6 +46,7 @@ public class ConfigParam<T : Any>
* 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,
Comment thread
kirich1409 marked this conversation as resolved.
/**
* Category or group name for organizing related parameters.
Expand Down
2 changes: 2 additions & 0 deletions featured-bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading