Skip to content

Conversation

@kriscoleman
Copy link
Collaborator

Summary

This PR introduces a new pull command to the OpenFeature CLI that enables fetching flag configurations from remote sources. Key changes include:

  • New pull command: Fetches flag manifests from remote HTTP/HTTPS URLs or local file paths
  • Enhanced init command: Now supports --flag-source-url parameter to configure remote flag sources in .openfeature.yaml
  • Configuration management: Automatically creates and manages .openfeature.yaml config files to store flag source URLs and authentication tokens
  • Authentication support: Includes bearer token authentication for secure remote flag fetching
  • Interactive configuration: Prompts users for missing configuration values (URL, auth token) when not provided
  • Flexible manifest handling: Supports both creating new manifests and updating existing ones

Related Issues

#3

Architecture Changes

  • Refactored manifest loading: Extracted Load functionality from flagset package to avoid circular dependencies
  • New LoadFromSourceFlags function: Handles type normalization for different flag type representations (e.g., Boolean, bool, boolean)
  • Modular pull implementation: Separated remote fetching logic into internal/manifest/pull.go for better code organization
  • Enhanced config package: Added support for flag source URLs and auth tokens in configuration management

Testing

  • Added comprehensive unit tests for pull command functionality
  • Integrated HTTP mocking using h2non/gock for reliable remote source testing
  • Added Go and NodeJS integration tests to ensure cross-language compatibility
  • Updated CI/CD workflows to include new test scenarios

Future Enhancements

  • Support additional authentication methods beyond bearer tokens
  • Implement secure credential storage mechanism
  • Add support for more source providers (Git repositories, flagd)
  • Enable partial flag updates instead of full manifest overwrites
  • Add conflict resolution strategies for existing flag configurations

Usage Example

# Initialize with a remote flag source
openfeature init --flag-source-url https://api.example.com/flags

# Pull flags from configured source
openfeature pull

# Pull with specific output file
openfeature pull --output flags.json

@kriscoleman kriscoleman marked this pull request as ready for review July 19, 2025 17:11
@kriscoleman kriscoleman mentioned this pull request Jul 19, 2025
1 task
@beeme1mr beeme1mr requested review from anghelflorinm, bbland1, beeme1mr, cupofcat and sahidvelji and removed request for sahidvelji July 21, 2025 16:02
Copy link
Member

@beeme1mr beeme1mr left a comment

Choose a reason for hiding this comment

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

I'd like to test this end-to-end in a bit but I wanted to submit my initial feedback. Overall, it looks great. Nice job!

@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch 3 times, most recently from 7fc21f4 to fd302ab Compare July 22, 2025 16:09
Copy link
Member

@beeme1mr beeme1mr left a comment

Choose a reason for hiding this comment

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

Hey @kriscoleman, it's very close but the generated flags.json is invalid because the flag type is "int" instead of "integer".

You can reproduce this by running:

The issue affects "flag3" in the manifest.

Copy link
Collaborator Author

@kriscoleman kriscoleman left a comment

Choose a reason for hiding this comment

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

just going back through again and I noticed that the integer flag in flags.json it throwing an "incorrect type" error (expecting boolean), but i can manually correct it to `integer and it's all good.

my intial thought would be changing the IntType return to "integer" instead of the "int" would make sure that the logic holds to the json-schema validation and fix that but that could be too narrow of a focus on my part.

thank you! btw, what extension are you using to show that validation in your IDE? I love that

from what i can tell everything is still 👍🏽, but in case it caused any issues i missed wanted to atleast mention it here. 😄

Screenshot 2025-07-22 at 2 55 30 PM

Copy link
Collaborator Author

@kriscoleman kriscoleman left a comment

Choose a reason for hiding this comment

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

Perhaps it's just on my system, but I'm seeing a % at the end of this log line.

Image

yea I'm seeing it too, I'll address this

@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch from fd302ab to 50c5c6e Compare July 24, 2025 19:57
@beeme1mr
Copy link
Member

I approved but please consider #147 (comment) before merging.

…pull command

Signed-off-by: Jason Salaber <jcsalaber@hotmail.com>

feat: added prompts for default values if not defined

Signed-off-by: Jason Salaber <jcsalaber@hotmail.com>

chore: conditionally add auth header if auth token is not empty

Signed-off-by: Jason Salaber <jcsalaber@hotmail.com>

chore: added tests for pull command

Signed-off-by: Jason Salaber <jcsalaber@hotmail.com>

feat: added ability to pull from local file for source flags

Signed-off-by: Jason Salaber <jcsalaber@hotmail.com>

chore: refactor of  pull command
Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch from 50c5c6e to dc52554 Compare July 24, 2025 22:32
@kriscoleman
Copy link
Collaborator Author

I approved but please consider #147 (comment) before merging.

thanks, good call. I added in some logic to handle the prompt (but it also checks the override flag, if true, it just overrides)

@bbland1
Copy link
Member

bbland1 commented Jul 24, 2025

thank you! btw, what extension are you using to show that validation in your IDE? I love that

Screenshot 2025-07-22 at 2 55 30 PM

it this one called error lens! I’ve had it for so long I almost was like that is just what vs code does 😅. it has helped me so much in times of finding an error since it was more prominent!

@beeme1mr
Copy link
Member

Thanks @kriscoleman, looks good. I'll leave it open for more feedback until tomorrow. FYI @cupofcat @anghelflorinm

@beeme1mr beeme1mr closed this Jul 25, 2025
@beeme1mr beeme1mr reopened this Jul 25, 2025
Consolidates the conditional logic for creating or updating the
.openfeature.yaml file. This change improves readability and
reduces code duplication by using a flag to determine whether
the config file should be written.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Refactors remote flag loading to handle errors more gracefully.

This change ensures that the function returns nil immediately upon
encountering an error, preventing potential issues with uninitialized
flagsets. Additionally, initializes the flagset object only when
standard manifest parsing is attempted. It then returns the flagset
with source flags upon successful parsing.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch from c70849c to 2cc9cf3 Compare August 19, 2025 13:56
@beeme1mr
Copy link
Member

I'll give folks a day or two to finish reviews before merging. Thanks for getting this across the finish line @kriscoleman!

Refactors the prompt logic for integer and float default
values to use a new generic function.

This improves code reusability and reduces duplication by
centralizing the input validation logic.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Moves the prompt definition outside the switch statement to avoid
repetition and improves code readability.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Refactors the init command to improve readability and maintainability.

Moves logic for manifest creation and config file handling into
separate functions for better organization.

Introduces a confirmOverride function to reduce duplication and
improve user experience when overriding existing files.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
This commit improves error handling in the init command.

It addresses the issue where errors during confirmation prompts
were not being properly handled, leading to unexpected behavior.
Now, the application gracefully handles errors that may arise during
the confirmation prompt, providing a more robust user experience.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Refactors the way the default configuration file is generated.

Instead of using string concatenation, it uses a template to
generate the configuration file. This makes the configuration
file more readable and easier to maintain and allows to handle
conditional content.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Adds the ability to marshal a Flagset into JSON format, making
it compatible with the expected manifest structure. Also updates
the write function to use the new marshalling logic to properly
format the flags in the manifest file.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Refactors manifest creation and writing logic into separate, reusable functions.

This improves code readability and reduces duplication by extracting the
manifest creation and writing processes into dedicated functions. This
allows for more consistent handling of manifest operations across different
parts of the codebase.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Uses the abstract afero filesystem to read the flags file.
This change improves testability and allows for easier
manipulation of the filesystem in different environments.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Ensures that the manifest file is written to disk atomically.
This prevents potential data corruption or incomplete writes
if the process is interrupted during the write operation.

This implementation writes the manifest to a temporary file,
then renames it to the target path, guaranteeing atomicity.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Moves the promptWithValidation and promptForDefaultValue
functions to the bottom of the file. This improves code
organization and readability by grouping related
functionality together.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Fixes a bug where flag default values were not being correctly
handled when prompting the user for input. This commit updates
the code to use a pointer to the flag, ensuring that the
default value is correctly assigned after prompting.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Updates the error handling when unmarshaling JSON to provide a
more accurate error message.

Refactors the flagset writing process to directly process flag data,
avoiding intermediate marshaling and unmarshaling steps. This
simplifies the code and improves efficiency.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch from 2cc9cf3 to 22efb55 Compare August 28, 2025 20:00
@kriscoleman
Copy link
Collaborator Author

@beeme1mr & @cupofcat
pr has been updated

Refactors the flag source URL handling to use the `net/url` package.

This change improves the robustness and clarity of the code by
utilizing the `net/url` package to parse and validate the flag source
URL. It now supports `file`, `http`, and `https` schemes.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
@beeme1mr
Copy link
Member

Thanks! Let's try and merge this tomorrow.

Ensures that errors during temporary file removal are handled
gracefully, preventing potential resource leaks or incomplete
operations.

It prioritizes the original error during manifest writing/renaming
and logs the removal error to avoid masking the initial issue.

Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
Signed-off-by: Kris Coleman <kriscodeman@gmail.com>
@kriscoleman kriscoleman force-pushed the feat/openfeature-pull-command branch from 4e3e492 to 7065148 Compare August 29, 2025 04:42
@beeme1mr beeme1mr added this pull request to the merge queue Aug 29, 2025
Merged via the queue into open-feature:main with commit c517e87 Aug 29, 2025
6 checks passed
@kriscoleman kriscoleman mentioned this pull request Sep 30, 2025
5 tasks
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