Skip to content

feat(codereadiness): add hook for version-based flag validation - #904

Merged
beeme1mr merged 2 commits into
open-feature:mainfrom
marcin11858:feature/codereadiness-hook
Jul 20, 2026
Merged

feat(codereadiness): add hook for version-based flag validation#904
beeme1mr merged 2 commits into
open-feature:mainfrom
marcin11858:feature/codereadiness-hook

Conversation

@marcin11858

@marcin11858 marcin11858 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

feat(codereadiness): Introduce the codereadiness hook to control feature flag evaluation by comparing the application's current version with a required minimum version specified in the flag's metadata. If the comparator returns an error the hook also returns an error to trigger fallback to the default flag value.

This PR

Introduces the codereadiness hook under hooks/codereadiness to control feature flag evaluation based on the application's running code version.

How it works

  • Compares the application's current version with the required minimum version specified in the flag's metadata (by default, in the minCodeVersion key).
  • If the comparator returns an error (by default, if the current version in SemVer format is lower than the minimum), the hook propagates the error to trigger the SDK's fallback mechanism, returning the flag's default value.
  • The hook supports custom comparison logic (via WithComparator), custom metadata keys (via WithMetadataMinVerKey) and optional strict validation (via WithValidationRequired).

Notes

  • Includes comprehensive unit tests in codereadiness_test.go.
  • Includes a README.md with setup and configuration examples.

Follow-up Tasks

None.

How to test

Run the package unit tests:

cd hooks/codereadiness
go test -v ./...

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds the hooks/codereadiness Go module, release metadata, documentation, and license, plus an OpenFeature hook that compares current and minimum code versions from flag metadata. Tests cover constructor validation, metadata handling, custom options, and semver comparison.

Changes

Codereadiness hook and package setup

Layer / File(s) Summary
Module setup
.release-please-manifest.json, release-please-config.json, hooks/codereadiness/go.mod, hooks/codereadiness/LICENSE, hooks/codereadiness/README.md
Adds the new module metadata, release configuration, license text, and package README for hooks/codereadiness.
Hook configuration
hooks/codereadiness/pkg/codereadiness.go, hooks/codereadiness/README.md
Defines the hook state, option setters, constructor defaults, and option documentation for version comparison and metadata lookup.
Version validation
hooks/codereadiness/pkg/codereadiness.go
Implements After and the default semver comparator, including metadata handling, validation-required behavior, custom comparator wiring, and fallback logging.
Hook tests
hooks/codereadiness/pkg/codereadiness_test.go
Adds tests for constructor validation, metadata handling, custom options, comparator outcomes, and default comparator behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the new codereadiness hook for version-based flag validation.
Description check ✅ Passed The description accurately matches the new hook, tests, and documentation added in this changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@marcin11858 marcin11858 changed the title feat(codereadiness) add hook for version-based flag validation feat(codereadiness): add hook for version-based flag validation Jun 25, 2026
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch 6 times, most recently from 1cbe435 to f73bc0c Compare June 26, 2026 07:36
@marcin11858
marcin11858 marked this pull request as ready for review June 26, 2026 07:40
@marcin11858
marcin11858 requested review from a team as code owners June 26, 2026 07:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hooks/codereadiness/pkg/codereadiness.go`:
- Around line 58-61: The readiness check in codereadiness should treat a missing
FlagMetadata as a validation failure when strict validation is enabled, instead
of returning nil. Update the logic around FlagMetadata handling in
codereadiness.go so that the same validation path used for a missing
minCodeVersion key also runs when metadata is nil, while preserving the current
non-strict behavior.
- Around line 27-30: WithComparator currently allows a nil comparator to replace
the default from New(), which can make Hook.After panic on first use. Update
WithComparator to either ignore a nil argument and preserve the existing
comparator, or fail fast by rejecting nil before assigning h.comparator, using
the WithComparator and Hook.After flow as the main reference points.

In `@hooks/codereadiness/README.md`:
- Around line 69-77: The custom comparator example is missing the required fmt
import, so the snippet is not copy-pasteable as shown. Update the README example
around customComparator to either include fmt in the example’s imports or
replace fmt.Errorf with an error construction that does not require fmt,
ensuring the sample remains complete and directly usable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bde35c9-65a7-49c4-801d-2cf06c04e29d

📥 Commits

Reviewing files that changed from the base of the PR and between 10c5358 and f73bc0c.

⛔ Files ignored due to path filters (1)
  • hooks/codereadiness/go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • .release-please-manifest.json
  • hooks/codereadiness/LICENSE
  • hooks/codereadiness/README.md
  • hooks/codereadiness/go.mod
  • hooks/codereadiness/pkg/codereadiness.go
  • hooks/codereadiness/pkg/codereadiness_test.go
  • release-please-config.json

Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/codereadiness.go
Comment thread hooks/codereadiness/README.md
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from f73bc0c to e3c782f Compare June 26, 2026 08:12
@marcin11858
marcin11858 marked this pull request as draft June 30, 2026 13:27
@marcin11858
marcin11858 marked this pull request as ready for review July 1, 2026 05:31

@oxddr oxddr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good overall, I left couple of comments regarding style and clarity of the code.

Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/codereadiness.go
Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/codereadiness.go
Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/pkg/codereadiness_test.go Outdated
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch 2 times, most recently from f7c9bb7 to 1e06c44 Compare July 1, 2026 14:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
hooks/codereadiness/pkg/codereadiness_test.go (1)

98-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract a helper to reduce duplicated of.InterfaceEvaluationDetails boilerplate.

Nearly every test builds the same nested of.InterfaceEvaluationDetails{ EvaluationDetails: of.EvaluationDetails{ ResolutionDetail: of.ResolutionDetail{ FlagMetadata: ... } } } structure. A small helper (e.g. newDetails(metadata of.FlagMetadata) of.InterfaceEvaluationDetails) alongside newTestHook/newTestHookContext would remove this repetition across ~12 test functions and make each test body focus on the metadata under test.

♻️ Proposed helper
func newDetails(metadata of.FlagMetadata) of.InterfaceEvaluationDetails {
	return of.InterfaceEvaluationDetails{
		EvaluationDetails: of.EvaluationDetails{
			ResolutionDetail: of.ResolutionDetail{
				FlagMetadata: metadata,
			},
		},
	}
}

Also applies to: 116-122, 135-141, 153-159, 172-180, 192-199, 213-220, 233-240, 253-260, 270-277, 291-299, 312-319, 339-346, 363-370, 402-410

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hooks/codereadiness/pkg/codereadiness_test.go` around lines 98 - 104, The
test file repeats the same nested of.InterfaceEvaluationDetails construction in
many places, so add a small helper near newTestHook/newTestHookContext (for
example, newDetails(metadata of.FlagMetadata) of.InterfaceEvaluationDetails)
that builds the shared EvaluationDetails/ResolutionDetail wrapper with the
provided metadata. Then replace the duplicated inline boilerplate in the
affected test functions with calls to that helper so each test only specifies
the metadata it cares about.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@hooks/codereadiness/pkg/codereadiness_test.go`:
- Around line 98-104: The test file repeats the same nested
of.InterfaceEvaluationDetails construction in many places, so add a small helper
near newTestHook/newTestHookContext (for example, newDetails(metadata
of.FlagMetadata) of.InterfaceEvaluationDetails) that builds the shared
EvaluationDetails/ResolutionDetail wrapper with the provided metadata. Then
replace the duplicated inline boilerplate in the affected test functions with
calls to that helper so each test only specifies the metadata it cares about.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2e596a30-f18f-414e-975e-3ce9b315172b

📥 Commits

Reviewing files that changed from the base of the PR and between f7c9bb7 and 1e06c44.

⛔ Files ignored due to path filters (1)
  • hooks/codereadiness/go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • .release-please-manifest.json
  • hooks/codereadiness/LICENSE
  • hooks/codereadiness/README.md
  • hooks/codereadiness/go.mod
  • hooks/codereadiness/pkg/codereadiness.go
  • hooks/codereadiness/pkg/codereadiness_test.go
  • release-please-config.json
✅ Files skipped from review due to trivial changes (3)
  • .release-please-manifest.json
  • hooks/codereadiness/LICENSE
  • hooks/codereadiness/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • release-please-config.json
  • hooks/codereadiness/go.mod
  • hooks/codereadiness/pkg/codereadiness.go

@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch 8 times, most recently from 1e1e758 to a64e669 Compare July 2, 2026 09:45
Comment thread hooks/codereadiness/pkg/codereadiness.go Outdated
Comment thread hooks/codereadiness/pkg/codereadiness_test.go Outdated

@erka erka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this a flat package without pkg subpackage? I think we don't need it.

Comment thread hooks/codereadiness/codereadiness.go Outdated
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from c5f69f0 to ee015a3 Compare July 3, 2026 08:04
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch 2 times, most recently from 2012c46 to fabd180 Compare July 3, 2026 09:36
@marcin11858

Copy link
Copy Markdown
Contributor Author

Could we make this a flat package without pkg subpackage? I think we don't need it.

Done, removed pkg subpackage

@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from e63c606 to 043f662 Compare July 3, 2026 11:10
Comment thread .release-please-manifest.json
Comment thread hooks/codereadiness/codereadiness.go
@marcin11858
marcin11858 requested a review from erka July 8, 2026 10:24

@erka erka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks great!

Just one small nit: we've started adding GoDoc examples, and it would be great to include one here as well. Something along the lines of the example in the OpenFeature Go SDK:

https://github.com/open-feature/go-sdk/blob/main/openfeature/isolated/isolated_example_test.go

toddbaert
toddbaert previously approved these changes Jul 8, 2026
@toddbaert
toddbaert dismissed their stale review July 8, 2026 16:56

Questions

@toddbaert

toddbaert commented Jul 8, 2026

Copy link
Copy Markdown
Member

Code looks good ... one non-code question:

  • What is the main use case for this hook in real-world scenarios? If app-version v2.3.0 has my new feature, why would v2.2.0 of my code have the flag for it? In other words, can you give some examples of when I would have a flag in a version n-1 for a feature that should only be enabled in n? Is it for partially completed features? Like a code-level safety insurance?

@marcin11858

marcin11858 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Code looks good ... one non-code question:

  • What is the main use case for this hook in real-world scenarios? If app-version v2.3.0 has my new feature, why would v2.2.0 of my code have the flag for it? In other words, can you give some examples of when I would have a flag in a version n-1 for a feature that should only be enabled in n? Is it for partially completed features? Like a code-level safety insurance?

Thank you for your question. I found two possible use cases:

  • working on a complex task: The developer introduced reading feature flag in one of the PR but there is more PRs in a queue which are waiting for a review. When all PRs will be merge the code is ready and new feature can be enable safety.
  • bug in existing application: App-version with a new feature (v2.3.0) was developed but it has a bug. To be sure that any instance of your service will not turn on the feature in app version v2.3.0 the minCodeVersion can be changed to a new version with a fix e.g. v2.3.1. The developer is sure that is impossible to enable new feature in the v2.3.0 app version on any instance.

@marcin11858
marcin11858 requested a review from toddbaert July 9, 2026 06:33
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from 7bb18e4 to 8a71844 Compare July 9, 2026 07:35
@marcin11858

Copy link
Copy Markdown
Contributor Author

It looks great!

Just one small nit: we've started adding GoDoc examples, and it would be great to include one here as well. Something along the lines of the example in the OpenFeature Go SDK:

https://github.com/open-feature/go-sdk/blob/main/openfeature/isolated/isolated_example_test.go

Done. Added some examples in the hooks/codereadiness/example_test.go file.

@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from 31eac32 to 06fe6e8 Compare July 15, 2026 06:52
@oxddr

oxddr commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Code looks good ... one non-code question:

  • What is the main use case for this hook in real-world scenarios? If app-version v2.3.0 has my new feature, why would v2.2.0 of my code have the flag for it? In other words, can you give some examples of when I would have a flag in a version n-1 for a feature that should only be enabled in n? Is it for partially completed features? Like a code-level safety insurance?

Thank you for your question. I found two possible use cases:

  • working on a complex task: The developer introduced reading feature flag in one of the PR but there is more PRs in a queue which are waiting for a review. When all PRs will be merge the code is ready and new feature can be enable safety.
  • bug in existing application: App-version with a new feature (v2.3.0) was developed but it has a bug. To be sure that any instance of your service will not turn on the feature in app version v2.3.0 the minCodeVersion can be changed to a new version with a fix e.g. v2.3.1. The developer is sure that is impossible to enable new feature in the v2.3.0 app version on any instance.

The usefulness of this check is much more apparent with trunk-based development, i.e. single, stable main branch, from which releases are cut on regular basis (e.g. daily or weekly). In this setup, it's common, that a partially completed feature ends up in the new release. This hook is to provide code-level safety - as pointed by you. Internally, we pair it with some other safety mechanisms. This is our last line of defence.

Comment thread hooks/codereadiness/example_test.go Outdated
Comment thread hooks/codereadiness/example_test.go Outdated
Introduce the codereadiness hook to control feature flag evaluation
by comparing the application's current version with a required minimum
version specified in the flag's metadata. If the comparator returns
an error the hook also returns an error to trigger fallback to
the default flag value.

Signed-off-by: Marcin Wlazły <marcinwlazly@google.com>
@marcin11858
marcin11858 force-pushed the feature/codereadiness-hook branch from 4bdc096 to 477b371 Compare July 15, 2026 12:37
@toddbaert

Copy link
Copy Markdown
Member

I'm ready to merge this, but please consider my question here first! 🙏

@beeme1mr
beeme1mr merged commit 0b66633 into open-feature:main Jul 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants