Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: prepare for automatic release #27

Merged
merged 9 commits into from
Sep 27, 2023
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
42 changes: 42 additions & 0 deletions .github/workflows/lint-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: 'Lint PR'

on:
pull_request_target:
types:
- opened
- edited
- synchronize

jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: marocchino/sticky-pull-request-comment@v2
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.

Details:

```
${{ steps.lint_pr_title.outputs.error_message }}
```

# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
delete: true
47 changes: 47 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This workflow creates a running release please PR, which tracks all changes
# based on semantic PR titles. When that PR is merged, a publish occurs after
# release please increments the version.

on:
push:
branches:
- main

name: Run Release Please
permissions:
contents: read

jobs:
release-please:
permissions:
contents: write # for google-github-actions/release-please-action to create release commit
pull-requests: write # for google-github-actions/release-please-action to create release PR
runs-on: ubuntu-latest

# Release-please creates a PR that tracks all changes
steps:
- uses: google-github-actions/release-please-action@v3
id: release
with:
command: manifest
token: ${{secrets.GITHUB_TOKEN}}
default-branch: main
outputs:
release_created: ${{ steps.release.outputs.release_created }}
release_tag_name: ${{ steps.release.outputs.tag_name }}

cargo-publish:
needs: release-please
runs-on: ubuntu-latest
if: ${{ needs.release-please.outputs.release_created }}
steps:
- name: checkout
uses: actions/checkout@v3
with:
ref: ${{ needs.release-please.outputs.release_tag_name }}

- name: Publish
run: |
cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
2 changes: 2 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ jobs:
- uses: actions/checkout@v4
- name: Build
run: cargo build --verbose
- name: Check formats
run: cargo fmt --check
- name: Run tests
run: cargo test --verbose
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ ".": "0.1.0" }
10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
name = "open-feature"
version = "0.1.0"
edition = "2021"
rust-version = "1.67.1"
description = "The official OpenFeature Rust SDK."
documentation = "https://docs.rs/open-feature"
readme = "README.md"
homepage = "https://openfeature.dev/"
repository = "https://github.com/open-feature/rust-sdk"
license = "Apache License, Version 2.0"

[badges]
maintenance = { status = "actively-developed" }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
<!-- x-release-please-start-version -->

<!-- TODO: update with your SDK repo and the latest release version
<a href="https://github.com/open-feature/my-sdk/releases/tag/v0.0.1">
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.0.1&color=blue&style=for-the-badge" />
<a href="https://github.com/open-feature/rust-sdk/releases/tag/v0.1.0">
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.1.0&color=blue&style=for-the-badge" />
</a>
-->

Expand All @@ -47,9 +47,11 @@ This package was built with Rust version `1.70.0`. Earlier versions might work,

Add the following content to the `Cargo.toml` file:

<!-- x-release-please-start-version -->
```toml
open-feature = { git = "https://github.com/open-feature/rust-sdk", branch = "main" }
open-feature = "0.1.0"
```
<!-- x-release-please-end -->

### Usage

Expand Down
65 changes: 65 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"packages": {
".": {
"release-type": "rust",
"prerelease": false,
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"extra-files": ["README.md"],
"changelog-sections": [
{
"type": "fix",
"section": "🐛 Bug Fixes"
},
{
"type": "feat",
"section": "✨ New Features"
},
{
"type": "chore",
"section": "🧹 Chore"
},
{
"type": "docs",
"section": "📚 Documentation"
},
{
"type": "perf",
"section": "🚀 Performance"
},
{
"type": "build",
"hidden": true,
"section": "🛠️ Build"
},
{
"type": "deps",
"section": "📦 Dependencies"
},
{
"type": "ci",
"hidden": true,
"section": "🚦 CI"
},
{
"type": "refactor",
"section": "🔄 Refactoring"
},
{
"type": "revert",
"section": "🔙 Reverts"
},
{
"type": "style",
"hidden": true,
"section": "🎨 Styling"
},
{
"type": "test",
"hidden": true,
"section": "🧪 Tests"
}
]
}
}
}
8 changes: 4 additions & 4 deletions src/api/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ impl OpenFeature {

/// Return the metadata of named provider (a provider bound to clients with this name).
pub async fn named_provider_metadata(&self, name: &str) -> Option<ProviderMetadata> {
match self.provider_registry.get_named(name).await {
Some(provider) => Some(provider.get().metadata().clone()),
None => None,
}
self.provider_registry
.get_named(name)
.await
.map(|provider| provider.get().metadata().clone())
}

/// Create a new client with default name.
Expand Down
15 changes: 10 additions & 5 deletions src/api/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use super::{

/// The metadata of OpenFeature client.
pub struct ClientMetadata {
/// The name of client.
pub name: String,
}

Expand All @@ -24,7 +25,10 @@ pub struct Client {
global_evaluation_context: GlobalEvaluationContext,
}

/// The trait that converts a [`StructValue`] to a custom type.
/// It is used to return a custom type from `get_struct_value` and `get_string_details`.
pub trait FromStructValue<Out = Self> {
/// Construct type with given `value`.
fn from_struct_value(value: &StructValue) -> anyhow::Result<Out>;
}

Expand All @@ -48,6 +52,7 @@ impl Client {
&self.metadata
}

/// Set evaluation context to the client.
pub fn set_evaluation_context(&mut self, evaluation_context: EvaluationContext) {
self.evaluation_context = evaluation_context;
}
Expand Down Expand Up @@ -174,7 +179,7 @@ impl Client {
.await
.resolve_bool_value(flag_key, &context)
.await?
.to_evaluation_details(flag_key))
.into_evaluation_details(flag_key))
}

/// Return the [`EvaluationDetails`] with given `flag_key`, `evaluation_context` and
Expand All @@ -193,7 +198,7 @@ impl Client {
.await
.resolve_int_value(flag_key, &context)
.await?
.to_evaluation_details(flag_key))
.into_evaluation_details(flag_key))
}

/// Return the [`EvaluationDetails`] with given `flag_key`, `evaluation_context` and
Expand All @@ -212,7 +217,7 @@ impl Client {
.await
.resolve_float_value(flag_key, &context)
.await?
.to_evaluation_details(flag_key))
.into_evaluation_details(flag_key))
}

/// Return the [`EvaluationDetails`] with given `flag_key`, `evaluation_context` and
Expand All @@ -231,7 +236,7 @@ impl Client {
.await
.resolve_string_value(flag_key, &context)
.await?
.to_evaluation_details(flag_key))
.into_evaluation_details(flag_key))
}

/// Return the [`EvaluationDetails`] with given `flag_key`, `evaluation_context` and
Expand Down Expand Up @@ -292,7 +297,7 @@ impl Client {
}

impl<T> ResolutionDetails<T> {
fn to_evaluation_details(self, flag_key: impl Into<String>) -> EvaluationDetails<T> {
fn into_evaluation_details(self, flag_key: impl Into<String>) -> EvaluationDetails<T> {
EvaluationDetails {
flag_key: flag_key.into(),
value: self.value,
Expand Down
12 changes: 4 additions & 8 deletions src/api/provider_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ impl ProviderRegistry {
map.remove("");

provider
.initialize(&self.global_evaluation_context.get().await.borrow())
.initialize(self.global_evaluation_context.get().await.borrow())
.await;

map.insert(String::default(), FeatureProviderWrapper::new(provider));
}

pub async fn set_named<T: FeatureProvider>(&self, name: &str, mut provider: T) {
// Drop the already registered provider if any.
if let Some(_) = self.get_named(name).await {
if self.get_named(name).await.is_some() {
self.providers.write().await.remove(name);
}

provider
.initialize(&self.global_evaluation_context.get().await.borrow())
.initialize(self.global_evaluation_context.get().await.borrow())
.await;

self.providers
Expand All @@ -70,11 +70,7 @@ impl ProviderRegistry {
}

pub async fn get_named(&self, name: &str) -> Option<FeatureProviderWrapper> {
self.providers
.read()
.await
.get(name)
.map(|provider| provider.clone())
self.providers.read().await.get(name).cloned()
}

pub async fn clear(&self) {
Expand Down
5 changes: 5 additions & 0 deletions src/evaluation/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub struct EvaluationContext {
}

impl EvaluationContext {
/// Add `key` and `value` to the custom field of evaluation context.
#[must_use]
pub fn with_custom_field(
mut self,
key: impl Into<String>,
Expand All @@ -38,6 +40,7 @@ impl EvaluationContext {
self
}

/// Add `key` and `value` to the custom field of evaluation context.
pub fn add_custom_field(
&mut self,
key: impl Into<String>,
Expand All @@ -46,6 +49,8 @@ impl EvaluationContext {
self.custom_fields.insert(key.into(), value.into());
}

/// Merge `other` into `self` if corresponding field is not set.
/// Meaning values set into `self` has higher precedence.
pub fn merge_missing(&mut self, other: &Self) {
if self.targeting_key.is_none() {
if let Some(targeting_key) = &other.targeting_key {
Expand Down
Loading