We welcome contributions from the community! This document provides guidelines and instructions for contributing.
Please be respectful and constructive in all interactions with other contributors.
- Node.js 14+ (for testing)
- BrightScript tools (automatically installed as dev dependencies):
bslint- Grammar and best practices validationbrighterscript- Advanced BrightScript compiler
- (Optional) Roku device for integration testing
# Clone the repository
git clone https://github.com/growthbook/growthbook-roku.git
cd growthbook-roku
# Install dependencies
npm install
# Run tests to verify setup
npm testgit checkout -b feature/your-feature-name
# or for bug fixes:
git checkout -b fix/your-bug-fix-name- Follow the code style conventions (see below)
- Write clear, descriptive commit messages
- Test your changes
# Run all tests
npm test
# Validate BrightScript grammar & best practices (recommended)
npm run lint
# Check BrightScript compilation syntax
npm run syntax
# Alternative: Check syntax compilation directly
npm run syntax
# Run specific test file
node tests/validate-logic.js- Update relevant
.mdfiles - Add examples if applicable
- Update CHANGELOG.md
- Push your branch to GitHub
- Create a pull request with clear description
- Link related issues
- Wait for review and address feedback
File Structure:
' File header comment
' Purpose and overview
' ===================================================================
' Function name and purpose
' ===================================================================
function FunctionName(param1 as type, param2 as type) as returnType
' Implementation
return result
end functionNaming Conventions:
- Functions:
PascalCasefor public,_camelCasefor private - Variables:
camelCase - Constants:
UPPER_SNAKE_CASE
Comments:
' Single line comment
'
' Multi-line comment
' with multiple lines
'
' Section comment
' ===================================================================
' Inline comment for complex logicFormatting:
- 4-space indentation
- Blank line between functions
- Line length: max 100 characters
Test Organization:
runner.test('Feature name - action', () => {
// Arrange
const gb = new GrowthBookTest({ /* ... */ });
// Act
const result = gb.someMethod();
// Assert
assert.strictEqual(result, expected);
});Naming:
- Test names: descriptive, start with verb or feature name
- Variables:
camelCase - Use clear assertion messages
- Write unit tests first (TDD approach preferred)
- Implement feature in
source/GrowthBook.brs - All tests pass:
npm test - BrightScript syntax valid:
npm run lint - Add example if applicable in
examples/ - Update README.md if user-facing
- Update TESTING.md if testing-related
- Update CHANGELOG.md
- Add JSDoc/comments
- Write test first:
runner.test('myNewMethod returns correct value', () => {
const gb = new GrowthBookTest({ features: {...} });
const result = gb.myNewMethod('param');
assert.strictEqual(result, expected);
});- Implement in BrightScript:
function GrowthBook_myNewMethod(param as string) as string
' Implementation here
return result
end function- Add to SDK instance:
instance = {
' ... other methods
myNewMethod: GrowthBook_myNewMethod
}- Test and document
- Create an issue if one doesn't exist
- Create a test that reproduces the bug
- Fix the bug
- Verify test passes
- Update documentation if needed
- Submit PR with reference to issue
// Test that demonstrates the bug
runner.test('Bug: isOn returns true when should be false', () => {
const gb = new GrowthBookTest({
features: { 'buggy': { defaultValue: false } }
});
gb.init();
// This test fails before fix
assert.strictEqual(gb.isOn('buggy'), false);
});- Document new features
- Add examples
- Update table of contents if needed
- Keep examples current
Each public function should be documented:
' ===================================================================
' methodName - Brief description
'
' Parameters:
' param1 (type) - Description
' param2 (type) - Description
'
' Returns:
' type - Description of return value
'
' Example:
' result = gb.methodName("param1", "param2")
' ===================================================================
function GrowthBook_methodName(param1 as string, param2 as type) as returnType
' ...
end function- Test happy path
- Test edge cases
- Test error conditions
- Use descriptive names
- Test one thing per test
- Test feature interaction
- Test real-world scenarios
- Test with actual feature data structure
For performance-critical code:
runner.test('Performance: hashAttribute is fast', () => {
const gb = new GrowthBookTest();
const start = Date.now();
for (let i = 0; i < 1000; i++) {
gb._hashAttribute(`user${i}`);
}
const elapsed = Date.now() - start;
assert(elapsed < 100, `Too slow: ${elapsed}ms`);
});We follow Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
Update package.json version when appropriate.
- ✅ Tests pass
- ✅ No breaking changes (or justified)
- ✅ Clear commit messages
- ✅ Follows code style
- ✅ Documentation updated
- ✅ No unnecessary dependencies
- Automated tests run
- Maintainer review
- Request changes or approve
- You address feedback
- Maintainer merges
When releasing a new version:
- Update
package.jsonversion - Update CHANGELOG.md
- Create git tag:
git tag v1.0.0 - Push:
git push origin main --tags - Publish:
npm publish
- Check existing issues
- Read documentation
- Join Slack community
- Ask on GitHub Discussions
By contributing, you agree that your contributions will be licensed under the MIT License.
Feel free to open an issue or ask in our Slack community.
Thank you for contributing! 🎉