Contributing Guide¶
Welcome! This guide will get you up and running with the ml-container-creator codebase in minutes.
๐ฏ Quick Setup¶
Prerequisites¶
- Node.js 24.11.1+
- Git
Get Started (5 minutes)¶
# 1. Clone and install
git clone https://github.com/awslabs/ml-container-creator
cd ml-container-creator
npm install
npm link
# 2. Run tests to verify setup
npm test
# 3. Try the generator
yo ml-container-creator
That's it! You're ready to contribute.
๐ Project Structure¶
Understanding the codebase structure:
ml-container-creator/
โโโ generators/app/ # Main generator code
โ โโโ index.js # Generator entry point (orchestration)
โ โโโ lib/ # Modular components
โ โ โโโ prompts.js # Prompt definitions
โ โ โโโ prompt-runner.js # Prompt orchestration
โ โ โโโ template-manager.js # Template logic
โ โโโ templates/ # EJS templates for generated projects
โ โโโ code/ # Model serving code
โ โโโ deploy/ # Deployment scripts
โ โโโ sample_model/ # Sample training code
โ โโโ test/ # Test templates
โโโ test/ # Generator tests
โ โโโ generator.test.js # Integration tests
โ โโโ template-manager.test.js # Unit tests
โโโ docs/ # Documentation
๐ Understanding the Code¶
How the Generator Works¶
The generator follows a simple flow:
1. Prompting Phase (prompt-runner.js)
โ
Collects user configuration through interactive prompts
2. Validation Phase (template-manager.js)
โ
Validates configuration is supported
3. Writing Phase (index.js)
โ
Copies and processes templates based on configuration
Key Files to Know¶
generators/app/index.js - Main generator class
- Orchestrates the generation process
- Delegates to specialized modules
- ~50 lines (was 300+ before refactoring!)
generators/app/lib/prompts.js - Prompt definitions
- All user prompts organized by phase
- Easy to add new prompts
- Clear separation of concerns
generators/app/lib/template-manager.js - Template logic
- Determines which templates to include/exclude
- Validates user configuration
- Centralizes conditional logic
generators/app/lib/prompt-runner.js - Prompt orchestration
- Runs prompts in organized phases
- Provides user feedback
- Combines answers from all phases
๐ ๏ธ Common Tasks¶
Adding a New Prompt¶
- Add prompt definition to
generators/app/lib/prompts.js:
// In the appropriate phase array
{
type: 'list',
name: 'myNewOption',
message: 'Choose your option?',
choices: ['option1', 'option2'],
default: 'option1'
}
- Update
template-manager.jsif it affects template selection:
// In getIgnorePatterns() or validate()
if (this.answers.myNewOption === 'option1') {
patterns.push('**/some-template/**');
}
- Add test in
test/generator.test.js:
it('handles new option correctly', async () => {
await helpers.run(path.join(__dirname, '../generators/app'))
.withPrompts({ myNewOption: 'option1', /* ... */ });
assert.file(['expected-file.txt']);
});
Adding a New Template¶
- Create template file in
generators/app/templates/:
- Use EJS syntax for variables:
- Add exclusion logic if conditional (in
template-manager.js):
Running Tests¶
# Run all tests
npm test
# Run specific test file
npx mocha test/generator.test.js
# Run with verbose output
npx mocha test/generator.test.js --reporter spec
Testing Your Changes Locally¶
# 1. Make your changes
# 2. Re-link the generator
npm link
# 3. Test in a temporary directory
cd /tmp
yo ml-container-creator
# 4. Verify generated project
cd your-generated-project
docker build -t test .
๐ Debugging Tips¶
Enable Debug Output¶
# See detailed Yeoman output
DEBUG=yeoman:* yo ml-container-creator
# See generator-specific output
DEBUG=generator-ml-container-creator:* yo ml-container-creator
Common Issues¶
"Generator not found"
"Tests failing after changes"
"Template not being copied"
- Check template-manager.js for exclusion patterns
- Verify template path is correct
- Check EJS syntax is valid
๐ Code Style¶
We follow these conventions:
// โ
Good
const answers = await this.prompt([...]);
const { framework, modelServer } = this.answers;
// โ Avoid
var x = 5;
let y = this.answers.framework;
Key points:
- Use const by default, let when needed, never var
- Use arrow functions for callbacks
- Use template literals for strings
- Add JSDoc comments for public methods
- Keep functions small and focused
๐งช Testing Guidelines¶
What to Test¶
- โ File generation for different configurations
- โ Template exclusion logic
- โ Validation of user inputs
- โ Edge cases and error conditions
Test Structure¶
describe('feature name', () => {
beforeEach(async () => {
// Setup test environment
await helpers.run(path.join(__dirname, '../generators/app'))
.withPrompts({ /* test configuration */ });
});
it('should do something specific', () => {
// Assert expected behavior
assert.file(['expected-file.txt']);
});
});
๐ Making Your First Contribution¶
Good First Issues¶
Look for issues labeled:
- good first issue - Perfect for newcomers
- help wanted - Community contributions welcome
- documentation - Improve docs
Contribution Workflow¶
- Find an issue or create one describing your change
- Fork the repository and create a branch
- Make your changes following code style
- Add tests for your changes
- Run tests to ensure everything works
- Submit a PR with clear description
PR Checklist¶
Before submitting:
- [ ] Tests pass (npm test)
- [ ] Code follows style guidelines
- [ ] Documentation updated if needed
- [ ] Commit messages are clear
- [ ] PR description explains the change
๐ Additional Resources¶
- Adding Features Guide - Detailed guide for new features
- Coding Standards - Complete style guide
- Template System - How templates work
- Architecture - Complete architecture guide with visual overview
๐ฌ Getting Help¶
Stuck? We're here to help:
- Check existing documentation
- Search issues
- Ask in discussions
- Tag maintainers in your PR
๐ You're Ready!¶
You now know enough to start contributing. Don't worry about making mistakes - that's how we all learn. The maintainers are friendly and will help guide you through your first contribution.
Happy coding! ๐