Skip to content
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
1 change: 0 additions & 1 deletion .github/prompts/sc.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ Evaluate changed files in the repository and create commits following the Conven

## Constraints

- Project must pass linting and tests before staging and committing.
- Do not push changes to the remote repository.
- Do not combine unrelated changes into a single commit.
- Do not modify the content of the changes; only group, stage and commit.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ dist/
build/
*.log

# Husky
.husky/_

# Test coverage
coverage/
.nyc_output/
5 changes: 5 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
npx vitest run
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ jobs:
--api-key ${{ secrets.OPENAI_API_KEY }}
```

### With Custom Instructions

```yaml
- name: Generate Release Notes with Custom Style
run: |
npx github:davegarvey/bubble \
--latest \
--repo ${{ github.repository }} \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--api-key ${{ secrets.OPENAI_API_KEY }} \
--instructions-extend "- Use emojis for each category
- Highlight any security fixes in bold
- Include upgrade instructions for breaking changes"
```

## Configuration

Add your OpenAI API key to GitHub Secrets:
Expand All @@ -63,6 +78,68 @@ Add your OpenAI API key to GitHub Secrets:
3. Run "Release" workflow
4. Done! Check your releases page

## CLI Options

### Required Options

- `--latest` - Use the most recent tag (auto-detected)
- `--tag <tag>` - Specific Git tag to generate release notes for
- `--repo <repo>` - Repository in format `owner/repo` (or set `GITHUB_REPOSITORY` env var)
- `--api-key <key>` - API key for AI provider (or set `OPENAI_API_KEY` env var)

### Optional Options

- `--github-token <token>` - GitHub token for API access (or set `GITHUB_TOKEN` env var)
- `--dry-run` - Generate notes without creating release
- `--previous-tag <tag>` - Previous tag to compare against (auto-detected if not provided)
- `--provider <provider>` - AI provider to use (default: `openai`)
- `--model <model>` - AI model to use (default: `gpt-4-mini`)
- `--include-diffs` - Include git diffs for each commit to provide more context to AI
- `--include-readme` - Include README.md content for project context (default: true)

### Prompt Customization (CI/CD)

For CI/CD scenarios, you can customize the AI instructions:

- `--instructions <text>` - **Replace** the default instructions entirely with your custom instructions
- `--instructions-extend <text>` - **Extend** the default instructions by appending additional guidelines

**Examples:**

```bash
# Extend the default instructions with custom guidelines
npx github:davegarvey/bubble \
--latest \
--repo owner/repo \
--github-token $GITHUB_TOKEN \
--api-key $OPENAI_API_KEY \
--instructions-extend "- Include emoji indicators for each category\n- Mention any database migrations"

# Replace the entire instructions with custom ones
npx github:davegarvey/bubble \
--latest \
--repo owner/repo \
--github-token $GITHUB_TOKEN \
--api-key $OPENAI_API_KEY \
--instructions "You are a technical writer. Create brief release notes in bullet points. Focus only on breaking changes and new features."
```

**Default Behavior:** If neither option is specified, the tool uses its built-in default instructions unchanged.

**Architecture:** This tool uses OpenAI's Responses API with XML-tagged data for clear separation between instructions and commit information. See [Architecture Documentation](docs/adr/openai-responses-api-architecture.md) for details.

## Documentation

📚 **[Full Documentation](docs/README.md)**

- **Features**
- [Instructions Customization](docs/features/instructions-customization.md) - Detailed examples for different use cases

- **Architecture Decision Records (ADRs)**
- [ADR-001: XML-Tagged Data](docs/adr/ADR-001-xml-tagged-data.md) - Why we use XML tags
- [OpenAI Responses API Architecture](docs/adr/openai-responses-api-architecture.md) - System design and best practices
- [Instructions-Data Separation Implementation](docs/adr/instructions-data-separation-implementation.md) - Code changes and modifications

## Example Output

The AI generates well-structured release notes like:
Expand Down
34 changes: 32 additions & 2 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Command } from 'commander';
import dotenv from 'dotenv';
import { getCommitsSinceLastTag } from '../src/git.js';
import { getCommitsSinceLastTag, getDiffsSinceLastTag } from '../src/git.js';
import { generateReleaseNotes } from '../src/generator.js';
import { createOrUpdateRelease } from '../src/github.js';
import { getAIProvider } from '../src/ai/provider.js';
Expand All @@ -24,6 +24,9 @@ program
.option('--github-token <token>', 'GitHub token for API access', process.env.GITHUB_TOKEN)
.option('--dry-run', 'Generate notes without creating release', false)
.option('--previous-tag <tag>', 'Previous tag to compare against (auto-detected if not provided)')
.option('--instructions <text>', 'Custom instructions to replace the default instructions entirely')
.option('--instructions-extend <text>', 'Additional instructions to append to the default instructions')
.option('--include-diffs', 'Include git diffs for each commit to provide more context to AI', false)
.parse(process.argv);

const options = program.opts();
Expand Down Expand Up @@ -68,6 +71,28 @@ async function main() {

console.log(` Found ${commits.length} commits\n`);

// Get diffs for commits if requested (optional)
let commitDiffs = null;
if (options.includeDiffs) {
console.log('📋 Fetching commit diffs for additional context...');
commitDiffs = await getDiffsSinceLastTag(tag, options.previousTag);
const diffCount = Object.keys(commitDiffs).length;
console.log(` Found diffs for ${diffCount} commits\n`);
}

// Read README for project context (optional)
let readmeContent = null;
if (options.includeReadme) {
try {
const { readFileSync } = await import('fs');
readmeContent = readFileSync('README.md', 'utf-8');
console.log('📖 Found README.md for project context\n');
} catch (error) {
// README not found or not readable - continue without it
console.log('ℹ️ No README.md found, continuing without project context\n');
}
}

// Initialize AI provider
const aiProvider = getAIProvider(options.provider, {
apiKey: options.apiKey,
Expand All @@ -76,7 +101,12 @@ async function main() {

// Generate release notes
console.log('🤖 Generating release notes with AI...');
const releaseNotes = await generateReleaseNotes(commits, aiProvider);
const releaseNotes = await generateReleaseNotes(commits, aiProvider, {
customInstructions: options.instructions,
instructionsExtension: options.instructionsExtend,
readmeContent: readmeContent,
commitDiffs: commitDiffs
});

console.log('\n' + '='.repeat(80));
console.log('Generated Release Notes:');
Expand Down
63 changes: 63 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Bubble Documentation

Welcome to the Bubble documentation! This directory contains comprehensive guides and architectural decision records.

## 🎯 Features

User-facing documentation for features and capabilities:

- **[Instructions Customization](features/instructions-customization.md)** - Learn how to customize AI instructions for different use cases (open source, enterprise, APIs, etc.)

## 🏛️ Architecture Decision Records (ADRs)

Technical documentation about architecture and design decisions:

- **[ADR-001: XML-Tagged Data](adr/ADR-001-xml-tagged-data.md)** - Decision to use XML tags for wrapping commit data
- **[OpenAI Responses API Architecture](adr/openai-responses-api-architecture.md)** - Complete architectural design, separation of concerns, and why we use OpenAI's Responses API
- **[Instructions-Data Separation Implementation](adr/instructions-data-separation-implementation.md)** - Detailed implementation guide covering all code changes and modifications

## Quick Links

### For Users

- [Main README](../README.md) - Getting started and basic usage
- [Instructions Customization](guides/instructions-customization.md) - Customize AI behavior

### For Contributors

- [Architecture](adr/ARCHITECTURE.md) - Understand the system design
- [Implementation](adr/IMPLEMENTATION.md) - See what was built and how

## Documentation Structure

```
docs/
├── README.md (this file)
├── features/ # User-facing feature documentation
│ └── instructions-customization.md
└── adr/ # Architecture Decision Records
├── ADR-001-xml-tagged-data.md
├── openai-responses-api-architecture.md
└── instructions-data-separation-implementation.md
```

## Contributing to Docs

When adding new documentation:

1. **Features** - Place user-facing feature documentation in `features/`
2. **ADRs** - Place architectural decisions and technical design docs in `adr/`
3. **Index** - Update this README with links to new docs

### Naming Conventions

**Features:** Use descriptive, hyphenated names

- `instructions-customization.md`
- `github-actions-integration.md`

**ADRs:** Use contextual, descriptive names

- `ADR-001-xml-tagged-data.md` - Numbered ADRs for specific decisions
- `openai-responses-api-architecture.md` - Overall architecture descriptions
- `instructions-data-separation-implementation.md` - Implementation details
Loading