Skip to content

Latest commit

 

History

History
403 lines (283 loc) · 11.3 KB

File metadata and controls

403 lines (283 loc) · 11.3 KB

Contributing to OpenFeature JS Client

Thank you for your interest in contributing to the OpenFeature JS Client! This document provides guidelines for contributing to the project, with a focus on the release process.

Project Structure

This is a monorepo managed with Lerna that contains multiple packages:

  • @datadog/flagging-core - Runtime-agnostic flag-evaluation logic
  • @datadog/openfeature-browser - Browser-specific bindings for OpenFeature

The project uses fixed versioning, meaning all packages share the same version number and are released together. The version is managed centrally in lerna.json.

Development Setup

  1. Install dependencies:

    yarn install
  2. Build all packages:

    yarn build
  3. Run tests:

    yarn test
  4. Type checking:

    yarn typecheck
  5. Linting:

    yarn lint
    yarn lint:fix  # Auto-fix issues

Release Process

Prerequisites

  • Ensure you're not on the main branch (releases should be done from feature branches)
  • All tests must pass
  • Code must be linted and type-checked
  • Changes should be committed and pushed
  • Proper GitHub secrets must be configured:
    • NPM_PUBLISH_TOKEN_FLAGGING_CORE - Token for publishing core package
    • NPM_PUBLISH_TOKEN - Token for publishing browser package

Build Modes

The project supports different build modes that affect how the SDK version is determined:

1. Development Mode (dev)

  • Default mode when BUILD_MODE is not set
  • SDK version is set to "dev"
  • Used during development and testing

2. Release Mode (release)

  • Used for public releases
  • SDK version uses the actual version from lerna.json
  • This is the mode used for production releases

3. Canary Mode (canary)

  • Used on staging and production Datadog web app
  • SDK version format: {lerna-version}-{commit-sha}
  • Example: 0.1.0-alpha.2-a1b2c3d4

SDK Setups

The project also supports different SDK setups:

  • npm (default) - For npm package distribution
  • cdn - For CDN distribution

Creating a Release

All packages are published with the latest npm tag.

Step 1: Prepare for Release

  1. Switch to a feature branch:
    git checkout -b release/v1.2.3

Step 2: Prepare Package Dependencies

  1. Update the version using the CLI:

    yarn release

    This command:

    • Validates you're not on the main branch
    • Runs lerna version --exact --force-publish to update the version
    • Prompts for the new version number (applied to all packages)
    • Creates version commits and tags
    • Updates all package versions to match
    • Pushes version tag to Github

Step 3: Publish via GitHub Release

Publishing is fully automated via GitHub workflows!

  1. Create a GitHub Release:

    • Go to the GitHub repository
    • Click "Releases" → "Create a new release"
    • Set the tag to match your version (e.g., v1.1.0)
    • Add release notes describing your changes or use the Generate Release Notes button
    • Click "Publish release"
  2. Automated Publishing Workflow:

    The release.yaml workflow will automatically trigger and:

    Validation Phase:

    • Checks that the GitHub release tag matches the version in lerna.json
    • Fails fast if validation doesn't pass

    Build and Publish Phase:

    • Installs dependencies with yarn install --immutable
    • Builds all packages in release mode (BUILD_MODE=release)
    • Creates package tarballs with yarn lerna run pack --stream

    Publishing Sequence:

    1. Publishes core package first (@datadog/flagging-core)
    2. Waits for npm registry propagation
      • Polls npm registry for up to 5 minutes
      • Ensures core package is available before proceeding
      • Prevents dependency resolution issues
    3. Publishes browser package (@datadog/openfeature-browser)
    4. Publishes node-server package (@datadog/openfeature-node-server)

Package-Specific Build Commands

Core Package (@datadog/flagging-core)

# Build all formats (CommonJS and ESM)
cd packages/core
yarn build

# Build CommonJS only
yarn build:cjs

# Build ESM only
yarn build:esm

# Create package tarball
yarn pack

Browser Package (@datadog/openfeature-browser)

# Build all formats (CommonJS, ESM, and bundle)
cd packages/browser
yarn build

# Build bundle for CDN
SDK_SETUP=cdn yarn build:bundle

# Build CommonJS only
yarn build:cjs

# Build ESM only
yarn build:esm

# Create package tarball
yarn pack

Environment Variables

  • BUILD_MODE: Controls the SDK version format

    • dev (default) - Development version
    • release - Production release version
    • canary - Canary version with commit SHA
  • SDK_SETUP: Controls the SDK setup type

    • npm (default) - For npm distribution
    • cdn - For CDN distribution

Version Management

Since this project uses fixed versioning:

  • All packages share the same version number (managed in lerna.json)
  • When running yarn release, Lerna will prompt for a single version update
  • All package versions are automatically synchronized
  • Peer dependencies are automatically updated to match the fixed version
  • A single version commit and tag is created for the entire project

Automated Release Workflow Details

The GitHub Actions workflow (release.yaml) includes several safety measures:

  1. Version Consistency Check:

    • Compares GitHub release tag with lerna.json version
    • Ensures tags and versions are synchronized
  2. Dependency Coordination:

    • Core package is published first
    • Waits for npm registry propagation (up to 5 minutes)
    • Browser package gets updated core dependency automatically
  3. Build Integrity:

    • Uses BUILD_MODE=release for production builds
    • Replaces build environment variables correctly
    • Creates both npm packages and CDN bundles

Testing Before Release

  1. Run all tests:

    yarn test
  2. Type checking:

    yarn typecheck
  3. Linting:

    yarn lint
  4. Build verification:

    yarn clean
    yarn build
    yarn build:bundle
  5. Package creation test:

    yarn version  # Test dependency updates and package creation

Troubleshooting

Common Issues

  1. Release from main branch:

    • Error: "please do not release from main branch"
    • Solution: Create a feature branch for releases
  2. Version mismatch in GitHub workflow:

    • Error: "Release tag doesn't match lerna.json version"
    • Solution: Ensure the GitHub release tag exactly matches v{version} format where {version} is from lerna.json
  3. Build environment issues:

    • Ensure BUILD_MODE and SDK_SETUP are set correctly
    • Check that all dependencies are installed
  4. Version synchronization issues:

    • Run yarn version to update peer dependencies
    • Check that all package versions match the version in lerna.json
  5. GitHub workflow failures:

    • Check the Actions tab for detailed error logs
    • Ensure GitHub secrets are properly configured:
      • NPM_PUBLISH_TOKEN_FLAGGING_CORE for core package
      • NPM_PUBLISH_TOKEN for browser package
    • Verify the release tag matches the version in lerna.json
  6. npm registry propagation delays:

    • The workflow waits up to 5 minutes for the core package to be available
    • If this fails, it may indicate npm registry issues
    • Check npm status page or try republishing manually
  7. Webpack build issues:

    • Ensure all TypeScript configurations are valid
    • Check that webpack configurations in each package are correct
    • Verify all required dependencies are installed

Getting Help

  • Check the README.md for basic project information
  • Review the scripts in the scripts/ directory for implementation details
  • Check the GitHub Actions tab for workflow status and logs
  • Examine the scripts/cli script for available commands (release, version, typecheck, lint)
  • Open an issue on GitHub for bugs or feature requests

Manual Publishing (Emergency Only)

If the automated workflow fails and you need to publish manually:

  1. Build packages:

    BUILD_MODE=release yarn build
    yarn version
  2. Publish core package:

    cd packages/core
    npm publish --tag latest
  3. Wait for propagation, then publish remaining packages:

    cd packages/browser
    npm publish --tag latest
    cd ../node-server
    npm publish --tag latest

Third-Party Licenses

All third-party dependency licenses are tracked in LICENSE-3rdparty.csv. This file is auto-generated and must be kept up to date whenever dependencies change. CI will fail if it is stale.

When to update

Re-generate the file whenever you add, remove, or update a dependency in any package.json.

Prerequisites

Requirement Details
Python 3.11.12 pyenv install 3.11.12 && pyenv local 3.11.12
Go 1.23+ Required by dd-license-attribution
dd-license-attribution pip install dd-license-attribution (repo)
GITHUB_TOKEN See below

For Datadog employees, see the internal dd-license-attribution guide.

Setting GITHUB_TOKEN

If you already use the GitHub CLI, the easiest option is:

export GITHUB_TOKEN=$(gh auth token)

Otherwise, create a fine-grained personal access token with read access to Contents and Metadata at https://github.com/settings/personal-access-tokens and export it:

export GITHUB_TOKEN="github_pat_..."

Generating / updating licenses

export GITHUB_TOKEN=$(gh auth token)
yarn licenses:generate

This overwrites LICENSE-3rdparty.csv with the latest data. Commit the result.

Validating licenses locally

yarn licenses:validate

This checks that every npm package in yarn.lock has a corresponding entry in the CSV. No external tools or tokens are needed — it runs in CI the same way. If it fails, run yarn licenses:generate and commit the result.

Code Style

  • Use TypeScript for all new code
  • Follow the existing code style and patterns
  • Run yarn lint:fix before committing
  • Ensure all tests pass before submitting changes

Commit Messages

Follow conventional commit format with gitmoji:

  • ✨ feat: for new features
  • 🐛 fix: for bug fixes
  • 📝 docs: for documentation changes
  • 🎨 style: for formatting changes
  • ♻️ refactor: for code refactoring
  • ✅ test: for test changes
  • 👷 chore: for maintenance tasks

Example: ✨ feat(browser): add new flag evaluation method