Skip to content

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

  1. 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'
}
  1. Update template-manager.js if it affects template selection:
// In getIgnorePatterns() or validate()
if (this.answers.myNewOption === 'option1') {
    patterns.push('**/some-template/**');
}
  1. 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

  1. Create template file in generators/app/templates/:
# Example: Add a new deployment script
touch generators/app/templates/deploy/my-script.sh
  1. Use EJS syntax for variables:
#!/bin/bash
PROJECT_NAME="<%= projectName %>"
REGION="<%= awsRegion %>"
  1. Add exclusion logic if conditional (in template-manager.js):
if (this.answers.framework !== 'sklearn') {
    patterns.push('**/deploy/my-script.sh');
}

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"

# Re-link the generator
cd ml-container-creator
npm link

"Tests failing after changes"

# Clear npm cache
npm cache clean --force
npm install

"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

  1. Find an issue or create one describing your change
  2. Fork the repository and create a branch
  3. Make your changes following code style
  4. Add tests for your changes
  5. Run tests to ensure everything works
  6. 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

๐Ÿ’ฌ Getting Help

Stuck? We're here to help:

  1. Check existing documentation
  2. Search issues
  3. Ask in discussions
  4. 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! ๐Ÿš€