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
58 changes: 43 additions & 15 deletions PR-FEED-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ This script generates RSS/Atom feeds and markdown pages from recently merged pul

## Features

- Fetches merged PRs from **both** repositories:
- Fetches merged PRs from **both** repositories:
- **Private**: `rundeckpro/rundeckpro` (filtered by `release-notes/include` label)
- **Public**: `rundeck/rundeck` (filtered by `release-notes/include` label)
- **Tag-based comparison**: Uses git tags instead of dates for accurate PR detection
- **SaaS cut support**: Limits PRs to those included in the most recent SaaS deployment cut
- **Submodule awareness**: Automatically finds the correct rundeck commit from rundeckpro tags
- **All merge strategies**: Handles merge commits, squash merges, and rebase merges
- Combines and sorts PRs by merge date across both repos
- Automatically removes `RUN-XXXX` prefixes from PR titles (matching notes.mjs logic)
- Generates both RSS 2.0 and Atom feeds
- Creates VuePress-compatible markdown pages
- Template-based content using Nunjucks (like notes.mjs)
- Comprehensive error handling
- **Tag-based comparison**: Uses git tags instead of dates for accurate PR detection
- **SaaS cut support**: Limits PRs to those included in the most recent SaaS deployment cut
- **Submodule awareness**: Automatically finds the correct rundeck commit from rundeckpro tags
- **All merge strategies**: Handles merge commits, squash merges, and rebase merges
- Combines and sorts PRs by merge date across both repos
- Automatically removes `RUN-XXXX` prefixes from PR titles (matching notes.mjs logic)
- Generates both RSS 2.0 and Atom feeds
- Creates VuePress-compatible markdown pages
- Template-based content using Nunjucks (like notes.mjs)
- Comprehensive error handling

## Initial Setup (One-time)

Expand Down Expand Up @@ -295,24 +295,46 @@ node ./docs/.vuepress/pr-feed.mjs --output-dir=./docs/some-other-location

## Implementation Notes

### Shared Utilities with notes.mjs

Both `pr-feed.mjs` and `notes.mjs` now use shared functions from `pr-utils.mjs`:

**Shared Functions:**
- `fetchPRsBetweenTags()` - Compare two git tags to find all PRs
- `extractPRSection()` - Extract specific sections from PR bodies (e.g., "Release Notes")
- `cleanPRTitle()` - Remove RUN-XXXX prefixes from PR titles
- `parseSaasCutTag()` - Parse SaaS cut tag format to extract commit SHAs
- `getPreviousVersion()` - Auto-decrement version numbers (e.g., 5.17.0 → 5.16.0)

This ensures consistent behavior across both scripts and reduces code duplication.

### Pattern Matching with notes.mjs

This script follows the same patterns as `notes.mjs`:
- Uses ES modules (`.mjs` extension)
- Uses Nunjucks templates for content generation
- Uses Octokit for GitHub API access
- Loads environment variables with `dotenv`
- Parses CLI arguments with `yargs`
- Follows the same code style and structure
- Both now use tag-based comparison (not milestones)

### Key Differences from notes.mjs

- **SaaS vs Self-Hosted**: Focuses on SaaS deployments vs version-specific self-hosted releases
- **Tag-based comparison**: Uses git tag comparison instead of milestone-based PR queries
- **Continuous updates**: Generates standalone pages for ongoing updates vs one-time release notes
- **SaaS cut awareness**: Limits PRs to those in the deployment cut (not everything in main)
- **Submodule handling**: Automatically resolves rundeck submodule commits from rundeckpro tags
- **Continuous updates**: Generates standalone pages for ongoing updates
- **Customer communication**: Designed for SaaS customers via RSS/Atom feeds
- **All merge strategies**: Handles merge commits, squash merges, and rebase merges
- **Shared logic**: Uses same PR title cleaning regex as notes.md.nj template
- **Feed generation**: Creates RSS 2.0 and Atom 1.0 feeds

### Similarity to notes.mjs

- **Both use tag-based comparison**: Compare git tags to find PRs between releases
- **Both handle all merge strategies**: Merge commits, squash merges, and rebase merges
- **Both use shared utilities**: Common functions from `pr-utils.mjs`
- **Both extract PR sections**: Pull "Release Notes" sections from PR bodies
- **Both filter by labels**: Use `release-notes/include` for enterprise PRs

## Technical Details

Expand All @@ -338,6 +360,12 @@ The script parses this format to extract commit SHAs directly, eliminating the n

This ensures the exact commits used in the build are compared, guaranteeing accuracy.

## Related Documentation

- **[README.md](./README.md)** - Main documentation project setup and release notes generation
- **`notes.mjs`** - Self-hosted release notes generator (uses same shared utilities)
- **`pr-utils.mjs`** - Shared utility functions used by both scripts

## License

This script is part of the Rundeck documentation project and follows the same license as the main repository.
203 changes: 183 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,42 +84,150 @@ The documentation is organized as follows:

# How to Create Release Notes

Rundeck Core PRs are included by default.
Core PRs can excluded by labeling them with the `release-notes/exclude` label.
## Prerequisites

Rundeck Enterprise PRs are excluded by default.
Enterprise PRs can be included by labeling them with the `release-notes/include` label.
### GitHub API Token Setup

Create the file `.env` in the project root and add the line `GH_API_TOKEN=[TOKEN]`
replacing `[TOKEN]` with your GitHub API token. This token needs `repo` scope.
Create a `.env` file in the project root:

```bash
# Create .env file
touch .env

# Add your GitHub API token
echo "GH_API_TOKEN=ghp_your_actual_token_here" > .env
```

Get a token at: https://github.com/settings/tokens

**Required permissions:**
- `repo` - Full control of private repositories
- Access to `rundeckpro/rundeckpro` (private)
- Access to `rundeckpro/sidecar` (private)

### PR Labeling

Both Rundeck Core and Enterprise repositories use the **`release-notes/include`** label:
- PRs with this label will be included in release notes
- PRs without this label will be excluded

**Release Notes Sections:**
The script automatically extracts content from the `## Release Notes` section in PR descriptions. Structure your PRs like this:

```markdown
## Release Notes
Brief customer-facing description of the change.
This content will appear in the generated release notes.

## Technical Details
Implementation specifics (not included in release notes).
```

## Tag-Based Release Notes (Current Approach)

The release notes script uses **git tag comparison** to find all PRs between two releases. This ensures accuracy by capturing all changes in the actual git history.

Run the following with the milestone for the release. This will create/overwrite an existing entry for the release and automatically update related documentation and configuration files:
### Basic Usage

```bash
npm run notes -- --milestone=${1?milestone name}
# Generate release notes (auto-detects previous version)
# Example: 5.17.0 automatically compares with 5.16.0
npm run notes -- --milestone=5.17.0
```

When run, the script will:
- Generate release notes for the specified milestone.
- This will require edits for proper dates, the Overview, etc.
- Add a new row for the release in `docs/history/release-calendar.md`.
- This file will require an update to the release date.
- Update `.docsearch/config.json` to set the correct version for search indexing.
- Update `docs/.vuepress/setup.js` with the new version information.
- Add the new version link to the sidebar in `docs/.vuepress/sidebar-menus/history.ts`.
### Version Auto-Detection

> Use wisely: running this command will overwrite existing release notes for the specified release and possibly duplicate config file updates.
| Target Version | Auto-detected Previous | What it compares |
|---------------|------------------------|------------------|
| `5.17.0` | `5.16.0` | All PRs between v5.16.0 and v5.17.0 tags |
| `5.17.1` | `5.17.0` | All PRs between v5.17.0 and v5.17.1 tags |
| `5.0.0` | `4.17.0` | All PRs between v4.17.0 and v5.0.0 tags |

## Draft Release Notes
### Custom Version Range

Run the following with the milestone for the release. This will create the file named draft.md to avoid overwriting any existing version:
For patch releases or special cases, specify the previous version:

```bash
npm run notes -- --milestone=${1?milestone name} --draft
# Compare 5.17.0 to 5.17.1
npm run notes -- --milestone=5.17.1 --from-version=5.17.0
```

### Draft Mode (Recommended for Testing)

Generate a draft without modifying configuration files:

```bash
# Creates docs/history/5_x/draft.md
npm run notes:draft -- --milestone=5.17.0

# Review the draft
cat docs/history/5_x/draft.md

# When satisfied, generate the final version
npm run notes -- --milestone=5.17.0
```

**Tag Detection:**
- If the tag exists (e.g., `v5.17.0`), draft mode uses the exact tag comparison
- If the tag doesn't exist yet, draft mode automatically uses `HEAD` to preview what will be in the release
- You'll see: "Warning: Tag 5.17.0 not found, using HEAD for preview"
- This allows you to preview release notes before creating the tag

## What the Script Does

When you run `npm run notes -- --milestone=5.17.0`, it will:

1. **Compare git tags** to find all PRs between versions (e.g., v5.16.0 → v5.17.0)
2. **Extract Release Notes sections** from PR bodies
3. **Collect contributor information** (excluding bots and internal accounts)
4. **Generate release notes markdown** at `docs/history/5_x/version-5.17.0.md`
5. **Update sidebar and navbar links** (unless `--draft` mode)
6. **Update configuration files**:
- `.docsearch/config.json` - Search indexing version
- `docs/.vuepress/setup.js` - Version information
- `docs/.vuepress/sidebar-menus/history.ts` - Version link
- `docs/.vuepress/navbar-menus/about.js` - Release notes link
- `docs/.vuepress/pr-feed-config.json` - PR feed baseline
7. **Handle all merge strategies** (merge commits, squash merges, rebase merges)

> **Note**: The generated file requires manual edits for dates, Overview section, and final descriptions.

## Typical Workflow

### Self-Hosted Release Process

```bash
# 1. Generate draft for review (before tagging)
# If tag doesn't exist yet, uses HEAD for preview
npm run notes:draft -- --milestone=5.17.0

# 2. Review the generated draft
code docs/history/5_x/draft.md

# 3. Create the version tag
git tag v5.17.0
git push origin v5.17.0

# 4. Generate final release notes (updates all configs)
# Now uses the exact tag for accurate PR detection
npm run notes -- --milestone=5.17.0

# 5. Edit the generated file for dates, overview, etc.
code docs/history/5_x/version-5.17.0.md

# 6. Commit all changes
git add docs/history/5_x/version-5.17.0.md
git add docs/.vuepress/sidebar-menus/history.ts
git add docs/.vuepress/navbar-menus/about.js
git add docs/.vuepress/setup.js
git add .docsearch/config.json
git add docs/.vuepress/pr-feed-config.json
git commit -m "Release notes for 5.17.0"
git push
```

**Note:** You can preview with draft mode before creating the tag. Draft mode will use HEAD if the tag doesn't exist yet.

## SaaS Development Updates Feed

For generating RSS/Atom feeds and markdown pages showing recent PRs deployed to the SaaS platform (but not yet in self-hosted releases), see [PR-FEED-README.md](./PR-FEED-README.md).
Expand All @@ -132,6 +240,61 @@ npm run pr-feed

The feed date range is automatically updated when you create release notes - no manual configuration needed!

## Troubleshooting Release Notes

### "Tag X.Y.Z not found" Warning or Error

**In Draft Mode:**
- Shows warning: "Tag 5.18.0 not found, using HEAD for preview"
- Uses HEAD (main branch) to preview PRs
- This is normal before the tag is created

**In Final Mode:**
- Shows error: "Tag 5.18.0 not found. Create the tag first or use --draft mode."
- Creates a placeholder file with minimal content
- Re-run after creating the tag to populate with actual PRs

**Solution:**
1. Use draft mode to preview: `npm run notes:draft -- --milestone=5.18.0`
2. Create the tag when ready: `git tag v5.18.0 && git push origin v5.18.0`
3. Generate final notes: `npm run notes -- --milestone=5.18.0`

**For repo-specific warnings** (`docs`, `ansible-plugin`):
- This is normal - these repos don't use version tags
- They'll be skipped gracefully

### "GH_API_TOKEN environment variable is not set"

**Solution**: Create `.env` file with your GitHub token (see Prerequisites above).

### No PRs found

**Check**:
- Version range is correct
- Tags exist in the repositories
- PRs are merged (not just closed)
- PRs have the required labels (`release-notes/include` for enterprise)

### Get Help

```bash
# View all available options
npm run notes -- --help
```

## Advanced Options

```bash
# Specify custom previous version
npm run notes -- --milestone=5.17.1 --from-version=5.17.0

# Draft mode (doesn't update configs)
npm run notes:draft -- --milestone=5.17.0

# Direct script usage
node ./docs/.vuepress/notes.mjs --milestone=5.17.0 --from-version=5.16.0
```

## Troubleshooting

If you encounter errors running the site locally, follow these steps to ensure a clean environment and proper setup:
Expand Down
Loading
Loading