diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index ab5a087..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Release Workflow - -on: - workflow_dispatch: - inputs: - new_version_type: - description: 'Auto-bump type (for generate)' - required: false - type: choice - options: - - none - - patch - - minor - - major - - rc - version: - description: 'Specific version (e.g., 1.2.0)' - required: false - from_version: - description: 'Compare from this version' - required: false - force: - description: 'Force overwrite' - required: false - default: 'none' - type: choice - options: - - none - - draft - - published - debug: - description: 'Enable debug output' - required: false - default: true - type: boolean - detect_mode: - description: 'Detection mode' - required: false - default: 'published' - type: choice - options: - - published - - all - config_path: - description: 'Path to config file' - required: false - default: '.release_tool.toml' - - issue_comment: - types: [created] - - pull_request: - types: [closed] - branches: - - 'release/**' - -jobs: - release-bot: - if: github.event_name != 'issue_comment' || startsWith(github.event.comment.body, '/release-bot ') - runs-on: ubuntu-latest - permissions: - contents: write - issues: write - pull-requests: write - packages: write - attestations: write - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Run Release Bot - uses: ./ # Uses the action from the root of this repository - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - version: ${{ inputs.version }} - new_version_type: ${{ inputs.new_version_type }} - from_version: ${{ inputs.from_version }} - force: ${{ inputs.force }} - debug: ${{ inputs.debug }} - config_path: ${{ inputs.config_path }} - detect_mode: ${{ inputs.detect_mode }} diff --git a/.release_tool.toml b/.release_tool.toml deleted file mode 100644 index ec1ce8c..0000000 --- a/.release_tool.toml +++ /dev/null @@ -1,1167 +0,0 @@ -config_version = "1.8" - -# ============================================================================= -# Release Tool Configuration -# ============================================================================= -# This file controls how the release tool generates release notes by managing: -# - Repository information and GitHub integration -# - Issue extraction and consolidation policies -# - Version comparison and gap detection -# - Release note categorization and formatting -# - Output destinations (file, GitHub release, PR) - -# ============================================================================= -# Repository Configuration -# ============================================================================= -[repository] -# code_repo (REQUIRED): The GitHub repository containing the code -# Format: "owner/repo" (e.g., "sequentech/voting-booth") -code_repo = "sequentech/release-bot" - -# issue_repos: List of repositories where issues are tracked -# If empty, uses code_repo for issues as well -# This is useful when issues are tracked in different repos than the code -# Default: [] (uses code_repo) -issue_repos = [] - -# ============================================================================= -# GitHub API Configuration -# ============================================================================= -[github] -# GITHUB_TOKEN environment variable is REQUIRED for API authentication -# The token needs the following permissions: -# - repo (for accessing repositories, PRs, issues) -# - write:packages (if creating releases) -# How to create: https://github.com/settings/tokens -# Set it as an environment variable: export GITHUB_TOKEN="ghp_..." - -# api_url: GitHub API base URL -# Change this only if using GitHub Enterprise Server -# Default: "https://api.github.com" -# For GitHub Enterprise: "https://github.yourcompany.com/api/v3" -api_url = "https://api.github.com" - -# ============================================================================= -# Database Configuration -# ============================================================================= -[database] -# path: Location of the SQLite database file for caching GitHub data -# The database stores PRs, commits, issues, and releases to minimize API calls -# Relative paths are relative to the current working directory -# Default: "release_tool.db" -path = "release_tool.db" - -# ============================================================================= -# Sync Configuration -# ============================================================================= -[sync] -# cutoff_date: Only fetch issues/PRs created after this date (ISO format: YYYY-MM-DD) -# This limits historical data fetching and speeds up initial sync -# Example: "2024-01-01" to only fetch data from 2024 onwards -# Default: null (fetch all historical data) -cutoff_date = "2025-01-01" - -# parallel_workers: Number of parallel workers for GitHub API calls -# Higher values = faster sync, but may hit rate limits more quickly -# Recommended: 5-20 depending on your API rate limit -# Default: 10 -parallel_workers = 10 - -# clone_code_repo: Whether to clone the code repository locally for offline operation -# When true, the generate-notes command can work without internet access -# Default: true -clone_code_repo = true - -# code_repo_path: Local path where to clone/sync the code repository -# If not specified, defaults to .release_tool_cache/{repo_name} -# Example: "/tmp/release_tool_repos/voting-booth" -# Default: null (uses .release_tool_cache/{repo_name}) -# code_repo_path = "/path/to/local/repo" - -# clone_method: Method for cloning repositories -# Options: -# - "https": Clone using HTTPS with GitHub token authentication -# Recommended for GitHub Actions with GITHUB_TOKEN -# - "ssh": Clone using SSH (git@github.com:owner/repo.git) -# Requires SSH keys to be configured -# - "auto": Try HTTPS first, fallback to SSH if it fails (DEFAULT) -# Provides flexibility across different environments -# Default: "auto" -# Use case: -# - GitHub Actions: Use "https" or "auto" (default) -# - Local development with SSH keys: Use "ssh" or "auto" -# - GitHub Enterprise: Use "https" with custom clone_url_template -clone_method = "auto" - -# clone_url_template: Custom clone URL template for non-standard Git hosting -# Use {repo_full_name} as a placeholder for the repository (e.g., "owner/repo") -# This is useful for GitHub Enterprise or custom Git servers -# If not specified, uses standard GitHub URLs based on clone_method -# Default: null (uses github.com) -# Examples: -# - GitHub Enterprise: "https://github.enterprise.com/{repo_full_name}.git" -# - Custom Git server: "https://git.company.com/{repo_full_name}.git" -# - SSH on custom port: "ssh://git@gitlab.company.com:2222/{repo_full_name}.git" -# clone_url_template = "https://github.enterprise.com/{repo_full_name}.git" - -# show_progress: Show progress updates during sync -# When true, displays messages like "syncing 13 / 156 issues (10% done)" -# Default: true -show_progress = true - -# ============================================================================= -# Issue Extraction and Consolidation Policy -# ============================================================================= -# patterns: Ordered list of issue extraction patterns -# Each pattern is associated with a specific extraction strategy (where to look) -# and uses Python regex with NAMED CAPTURE GROUPS (use "issue" group for the ID) -# -# Patterns are tried in ORDER (by the "order" field). First match wins. -# Lower order numbers = higher priority. You can reorder by changing the numbers. -# TIP: Put more specific/reliable patterns first (lower order), generic ones last -# -# Available strategies: -# - "branch_name": Extract from PR branch name (e.g., feat/meta-123/main) -# - "pr_body": Extract from PR description text -# - "pr_title": Extract from PR title -# - "commit_message": Extract from commit message text -# -# Pattern structure: -# [[issue_policy.patterns]] -# order = 1 # Priority (lower = tried first) -# strategy = "branch_name" # Where to look -# pattern = "regex_here" # What to match (use (?P\\d+) for ID) -# description = "explanation" # Optional: what this pattern matches - -# ORDER 1: Branch name (most reliable, structured format) -# Matches: feat/meta-123/main, fix/repo-456.whatever/develop -# Format: /-[.optional]/ -[[issue_policy.patterns]] -order = 1 -strategy = "branch_name" -pattern = "/(?P\\w+)-(?P\\d+)" -description = "Branch name format: type/repo-123/target" - -# ORDER 2: Parent issue URL in PR body (backup policy) -# Matches: "Parent issue: https://github.com/owner/repo/issues/999" -# Use this when the branch name doesn't follow convention -[[issue_policy.patterns]] -order = 2 -strategy = "pr_body" -pattern = "(Parent issue:.*?/issues/|sequentech/meta#)(?P\\d+)" -description = "Parent issue URL in PR description" - -# ORDER 3: GitHub issue reference in PR title -# Matches: "#123" in the PR title -[[issue_policy.patterns]] -order = 3 -strategy = "pr_title" -pattern = "#(?P\\d+)" -description = "GitHub issue reference (#123) in PR title" - -[issue_policy] -# no_issue_action: What to do when a commit/PR has no associated issue -# Valid values: -# - "ignore": Silently skip the warning, include in release notes -# - "warn": Print a warning but continue (RECOMMENDED for most teams) -# - "error": Stop the release note generation with an error -# Default: "warn" -# Use "error" for strict issue tracking, "warn" for flexibility -no_issue_action = "warn" - -# unclosed_issue_action: What to do with issues that are still open -# Valid values: -# - "ignore": Include open issues in release notes without warning -# - "warn": Print a warning but include them (RECOMMENDED) -# - "error": Stop if any issues are still open -# Default: "warn" -unclosed_issue_action = "warn" - -# partial_issue_action: What to do when an issue is extracted but not found in DB -# or found in a different repository than expected -# -# "Partial matches" occur when: -# - Issue key extracted from branch/PR, but issue not in database (common causes): -# * Issue created before your sync cutoff date -# * Issue doesn't exist (typo in branch name) -# * Sync hasn't been run yet -# - Issue found in database, but in wrong repository: -# * Branch says "meta-8624" but issue is in "step" repo -# * Mismatch between issue_repos config and actual issue location -# -# Valid values: -# - "ignore": Silently skip partial matches, continue with next pattern -# - "warn": Print detailed warnings with potential causes and issue links (RECOMMENDED) -# - "error": Stop release note generation if any partial matches found -# -# Default: "warn" -# When in warn mode, the tool will list: -# - Which issues had partial matches -# - Whether they were not found or in different repo -# - Potential reasons (cutoff date, typo, wrong repo, etc.) -# - Links to issues if found in different repos -partial_issue_action = "warn" - -# inter_release_duplicate_action: What to do when an issue appears in multiple releases -# This checks if issues in the new release already exist in semantically-earlier releases -# (e.g., creating 9.3.1 and finding issues that already appeared in 9.2.0) -# -# This happens when a single issue includes multiple PRs that land in different releases, -# or when backporting fixes to older release branches. -# -# Valid values: -# - "ignore": Exclude duplicate issues from the new release (keep only in earlier release) -# - "warn": Include duplicates but show a warning (RECOMMENDED) -# - "error": Stop release note generation if duplicates are found -# -# Default: "warn" -# Use "ignore" if you want strict deduplication (one issue per release across history) -# Use "warn" for visibility into which issues span multiple releases -inter_release_duplicate_action = "warn" - -# consolidation_enabled: Group multiple commits by their parent issue -# When true: Commits with the same issue (e.g., ISSUE-123) are grouped -# into a single release note entry -# When false: Each commit appears as a separate entry in release notes -# Default: true -# RECOMMENDED: true (makes release notes more concise and readable) -consolidation_enabled = true - -# release_notes_inclusion_policy: Control which types of changes appear in release notes -# This is a list of change types to include. Valid values: "issues", "pull-requests", "commits" -# -# Change Types: -# - "issues": Include commits/PRs that are associated with an issue -# - "pull-requests": Include PRs even if they don't have an associated issue -# - "commits": Include direct commits that have no PR and no issue -# -# How it works: -# - Changes are categorized by type: "issue", "pr", or "commit" -# - Only changes whose type is in this list will appear in release notes -# - Excluded changes won't appear in any category (including "Other") -# - Excluded changes won't be counted in statistics -# - Excluded changes are completely absent from the final output -# -# Common configurations: -# 1. Default ["issues", "pull-requests"] (RECOMMENDED): -# ✅ Include: Commits/PRs with issues -# ✅ Include: PRs without issues -# ❌ EXCLUDE: Standalone commits (no PR, no issue) -# Use case: Standard workflow where all significant work goes through PRs -# -# 2. Issues only ["issues"]: -# ✅ Include: Commits/PRs with issues -# ❌ EXCLUDE: PRs without issues -# ❌ EXCLUDE: Standalone commits -# Use case: Strict issue tracking, ignore untracked work -# -# 3. Everything ["issues", "pull-requests", "commits"]: -# ✅ Include: All changes regardless of type -# Use case: Small teams, less formal process, want complete history -# -# 4. PRs only ["pull-requests"]: -# ✅ Include: PRs without issues -# ❌ EXCLUDE: Commits/PRs with issues -# ❌ EXCLUDE: Standalone commits -# Use case: Unusual - only show untracked PRs -# -# Default: ["issues", "pull-requests"] -# This default works well for most teams using PR-based workflows -release_notes_inclusion_policy = ["issues", "pull-requests"] - -# description_section_regex: Regex to extract description from issue body -# Uses Python regex with capturing group (group 1 is extracted) -# Matches headers with any level (1-6 hashes) containing "Description" or "Summary" -# Stops at major section headers (1-2 hashes like "# Tasks", "## Other") -# Continues past nested sub-sections (### or more hashes) -# The tool gracefully handles issues without description sections -# Default: r'(?:#{1,6} (?:Description|Summary).*?)\n(.*?)(?=\n#{1,2} |\Z)' -# Set to empty string "" to disable description extraction -# NOTE: In TOML, backslashes must be doubled: \n becomes \\n, \Z becomes \\Z -description_section_regex = "(?:#{1,6} (?:Description|Summary).*?)\\n(.*?)(?=\\n#{1,2} |\\Z)" - -# migration_section_regex: Regex to extract migration notes from issue body -# Useful for database migrations, breaking changes, upgrade steps -# Matches headers with any level (1-6 hashes) containing "Migration" or "Migration Notes" -# Stops at major section headers (1-2 hashes like "# Tasks", "## Other") -# Continues past nested sub-sections (### or more hashes) -# The tool gracefully handles issues without migration sections -# Default: r'(?:#{1,6} (?:Migration|Migration Notes).*?)\n(.*?)(?=\n#{1,2} |\Z)' -# Set to empty string "" to disable migration notes extraction -# NOTE: In TOML, backslashes must be doubled: \n becomes \\n, \Z becomes \\Z -migration_section_regex = "(?:#{1,6} (?:Migration|Migration Notes).*?)\\n(.*?)(?=\\n#{1,2} |\\Z)" - -# ============================================================================= -# Version Comparison and Gap Detection Policy -# ============================================================================= -[version_policy] -# gap_detection: Check for missing versions between releases -# Detects gaps like 1.0.0 → 1.2.0 (missing 1.1.0) -# Valid values: -# - "ignore": Don't check for version gaps -# - "warn": Print a warning if gaps detected (RECOMMENDED) -# - "error": Stop the process if gaps are detected -# Default: "warn" -gap_detection = "warn" - -# tag_prefix: Prefix used for version tags in Git -# The tool will look for tags like "v1.0.0" if prefix is "v" -# Common values: "v", "release-", "" (empty for no prefix) -# Default: "v" -tag_prefix = "v" - -# ============================================================================= -# Branch Management Policy -# ============================================================================= -# Controls how release branches are created and managed -[branch_policy] -# release_branch_template: Template for release branch names (Jinja2 syntax) -# Use {{major}}, {{minor}}, {{patch}} as placeholders -# Examples: -# - "release/{{major}}.{{minor}}" → "release/9.1" -# - "rel-{{major}}.{{minor}}.x" → "rel-9.1.x" -# - "v{{major}}.{{minor}}" → "v9.1" -# Default: "release/{{major}}.{{minor}}" -release_branch_template = "release/{{major}}.{{minor}}" - -# default_branch: The default branch for new major versions -# New major versions (e.g., 9.0.0 when coming from 8.x.x) will branch from this -# Common values: "main", "master", "develop" -# Default: "main" -default_branch = "main" - -# create_branches: Automatically create release branches if they don't exist -# When true, the tool will create a new release branch automatically -# When false, you must create branches manually -# Default: true -create_branches = true - -# branch_from_previous_release: Branch new minor versions from previous release -# Controls the branching strategy for new minor versions: -# - true: 9.1.0 branches from release/9.0 (if it exists) -# - false: 9.1.0 branches from main (default_branch) -# This enables hotfix workflows where release branches persist -# Default: true -branch_from_previous_release = true - -# ============================================================================= -# Release Notes Categorization -# ============================================================================= -# Categories group release notes by the labels on issues/PRs -# Each category can match multiple labels, and has a display order -# -# Label Matching with Source Prefixes: -# You can specify where labels should match from using prefixes: -# - "pr:label_name" = Only match this label from Pull Requests -# - "issue:label_name" = Only match this label from Issues -# - "label_name" = Match from EITHER PRs or issues (default) -# -# This is useful when PRs and issues use the same label names differently. -# For example: -# - PRs might use "bug" for any bug-related code change -# - Issues might use "bug" only for confirmed bugs needing fixes -# - You can categorize them separately: ["pr:bug"] vs ["issue:bug"] -# -# Category structure: -# [[release_notes.categories]] -# name = "Display Name" # Shown in the release notes -# labels = ["label1", "pr:label2", "issue:label3"] # With optional prefixes -# order = 1 # Display order (lower numbers appear first) - -[release_notes] -# excluded_labels: Skip issues/PRs with these labels from release notes -# Useful for internal changes, CI updates, etc. -# excluded_labels = [ -# "skip-changelog", -# "internal", -# "wip", -# "do-not-merge", -# "release", -# ] -excluded_labels = [ - "skip-changelog", - "internal", - "wip", - "do-not-merge", - "release", -] - -# title_template: Jinja2 template for the release notes title -# Available variables: -# - {{ version }}: The version being released (e.g., "1.2.3") -# Default: "Release {{ version }}" -title_template = "Release {{ version }}" - -# entry_template: Jinja2 template for each individual release note entry -# This is a POWERFUL template that lets you customize exactly how each change -# appears in the release notes. You can use Jinja2 syntax including conditionals, -# loops, filters, and all available variables. -# -# IMPORTANT: HTML-like behavior for whitespace and line breaks -# - Multiple spaces/tabs are collapsed into a single space (like HTML) -# - New lines in the template are ignored unless you use
or
-# - Use
or
for explicit line breaks in the output -# - Use   for explicit spaces that won't collapse (e.g.,    = two spaces) -# - This allows multi-line templates for readability while controlling output -# -# Available variables for each entry: -# - {{ title }} : The title/summary of the change (string) -# Example: "Fix authentication bug in login flow" -# - {{ url }} : Smart link prioritizing issue over PR (string or None) -# Example: "https://github.com/owner/repo/issues/123" -# Priority: issue_url > pr_url -# - {{ issue_url }} : Direct link to the issue (string or None) -# Example: "https://github.com/owner/repo/issues/123" -# - {{ pr_url }} : Direct link to the pull request (string or None) -# Example: "https://github.com/owner/repo/pull/456" -# - {{ short_link }} : Short format link (string or None) -# Example: "#123" -# - {{ short_repo_link }} : Short format with repo name (string or None) -# Example: "owner/repo#123" -# - {{ pr_numbers }} : List of related PR numbers (list of int) -# Example: [123, 124] -# - {{ authors }} : List of author objects (list of dict) -# Each author is a dict with comprehensive information: -# - name: Git author name (e.g., "John Doe") -# - email: Git author email (e.g., "john@example.com") -# - username: GitHub login (e.g., "johndoe") -# - github_id: GitHub user ID (e.g., 12345) -# - display_name: GitHub display name -# - avatar_url: Profile picture URL -# - profile_url: GitHub profile URL -# - company: Company name -# - location: Location -# - bio: Bio text -# - blog: Blog URL -# - user_type: "User", "Bot", or "Organization" -# - identifier: Best identifier (username > name > email) -# - mention: @mention format (e.g., "@johndoe") -# - full_display_name: Best display name -# - {{ description }} : Extracted description text (string or None) -# Example: "This fixes the login flow by..." -# - {{ migration_notes }} : Extracted migration notes (string or None) -# Example: "Run: python manage.py migrate" -# - {{ labels }} : List of label names (list of string) -# Example: ["bug", "critical", "security"] -# - {{ issue_key }} : Issue identifier (string or None) -# Example: "#123" or "JIRA-456" -# - {{ category }} : Assigned category name (string or None) -# Example: "Bug Fixes" -# - {{ commit_shas }} : List of commit SHA hashes (list of string) -# Example: ["a1b2c3d", "e4f5g6h"] -# -# Jinja2 syntax examples: -# - Conditionals: {% if url %}...{% endif %} -# - Loops: {% for author in authors %}@{{ author.username }}{% endfor %} -# - Filters: {{ description|truncate(100) }} -# - Boolean check: {% if pr_numbers %}(#{{ pr_numbers[0] }}){% endif %} -# - Line breaks: Use
or
for new lines in output -# - Author fields: {{ author.username }}, {{ author.name }}, {{ author.mention }} -# -# Template examples: -# 1. Minimal (single line): -# entry_template = "- {{ title }}" -# -# 2. With PR link (single line): -# entry_template = "- {{ title }}{% if url %} ([#{{ pr_numbers[0] }}]({{ url }})){% endif %}" -# -# 3. With GitHub @mentions (uses author.mention for smart @username or name): -# entry_template = '''- {{ title }} -# {% if url %}([#{{ pr_numbers[0] }}]({{ url }})){% endif %} -# {% if authors %}
by {% for author in authors %}{{ author.mention }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}''' -# -# 4. With author names and emails: -# entry_template = '''- {{ title }} -# {% if authors %}
by {% for author in authors %}{{ author.name }} <{{ author.email }}>{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}''' -# -# 5. With author avatars and profile links (for markdown/HTML): -# entry_template = '''- {{ title }} -# {% if authors %}
by {% for author in authors %} {{ author.display_name }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}''' -# -# 6. Complex multi-line with labels, migration notes, and rich authors: -# entry_template = '''- {{ title }} -# {% if url %}([#{{ pr_numbers[0] }}]({{ url }})){% endif %} -# {% if labels %} `{{ labels|join('` `') }}`{% endif %} -# {% if authors %}
Contributors: {% for author in authors %}@{{ author.username or author.name }}{% if author.company %} ({{ author.company }}){% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %} -# {% if migration_notes %}
**Migration:** {{ migration_notes }}{% endif %}''' -# -# Default: Multi-line template with title, short_repo_link, and author mentions -# The whitespace will collapse,
tags create line breaks -# Uses author.mention which gives @username if available, otherwise falls back to name -# Uses short_repo_link for concise display (e.g., "meta#123" instead of full URL) -entry_template = '''- {{ title }}{% if url and short_repo_link %} ([{{ short_repo_link }}]({{ url }})){% elif url %} ([link]({{ url }})){% endif %} - {% if authors %} -   by {% for author in authors %}{{ author.mention }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}''' - -# release_output_template: MASTER Jinja2 template for GitHub release notes output -# This is an ADVANCED feature that gives you complete control over the release -# notes structure. When set, this template replaces the default category-based -# layout and lets you design your own custom format. -# -# WHEN TO USE: -# - You want a custom layout (e.g., flat list, grouped by type, etc.) -# - You need to iterate over migrations or descriptions across all issues -# - You want full control over the output structure -# -# IMPORTANT: HTML-like behavior for whitespace (same as entry_template) -# - Multiple spaces collapse to single space -# - Line breaks: Use
or
for new lines in output -# - Non-breaking spaces: Use   for explicit spaces that won't collapse -# -# Available variables: -# - {{ version }} : Version string (e.g., "1.2.3") -# - {{ title }} : Rendered release title (from title_template) -# - {{ year }} : Current year (e.g., "2025") -# - {{ categories }} : List of category dicts with 'name' and 'notes' -# - {{ all_notes }} : Flat list of all note dicts (across categories) -# - {{ render_entry(note) }}: Function to render a note using entry_template -# -# Each note dict contains: -# - title, url (prioritizes issue_url over pr_url), issue_url, pr_url -# - short_link (#123), short_repo_link (meta#123) -# - pr_numbers, commit_shas, labels, issue_key, category -# - description, migration_notes (processed, may be None) -# - authors (list of author dicts with all fields) -# -# Template examples: -# -# 1. Default category-based layout (equivalent to not setting output_template): -# output_template = '''# {{ title }} -# -# {% for category in categories %} -# ## {{ category.name }} -# {% for note in category.notes %} -# {{ render_entry(note) }} -# {% endfor %} -# {% endfor %}''' -# -# 2. Flat list without categories: -# output_template = '''# {{ title }} -# -# {% for note in all_notes %} -# {{ render_entry(note) }} -# {% endfor %}''' -# -# 3. Custom layout with migrations section: -# output_template = '''# {{ title }} -# -# ## Changes -# {% for note in all_notes %} -# {{ render_entry(note) }} -# {% endfor %} -# -# ## Migration Notes -# {% for note in all_notes %} -# {% if note.migration_notes %} -# ### {{ note.title }} -# {{ note.migration_notes }} -# {% endif %} -# {% endfor %}''' -# -# 4. Grouped by issue with full descriptions: -# output_template = '''# {{ title }} -# -# {% for note in all_notes %} -# ## {{ note.title }} -# {% if note.description %} -# {{ note.description }} -# {% endif %} -# {% if note.url %} -# **Pull Request:** [#{{ note.pr_numbers[0] }}]({{ note.url }}) -# {% endif %} -# {% if note.authors %} -# **Authors:** {% for author in note.authors %}{{ author.mention }}{% if not loop.last %}, {% endif %}{% endfor %} -# {% endif %} -# {% if note.migration_notes %} -# **Migration:** {{ note.migration_notes }} -# {% endif %} -# {% endfor %}''' -# -# 5. Custom grouping with manual entry rendering: -# output_template = '''# {{ title }} -# -# ## Features & Fixes -# {% for category in categories %} -# {% if category.name in ["Features", "Bug Fixes"] %} -# ### {{ category.name }} -# {% for note in category.notes %} -# {{ render_entry(note) }} -# {% endfor %} -# {% endif %} -# {% endfor %} -# -# ## Other Changes -# {% for category in categories %} -# {% if category.name not in ["Features", "Bug Fixes"] %} -# {% for note in category.notes %} -# - {{ note.title }}{% if note.url %} ([#{{ note.pr_numbers[0] }}]({{ note.url }})){% endif %} -# {% endfor %} -# {% endif %} -# {% endfor %}''' -# -# Default: Comprehensive template with breaking changes, migrations, descriptions, and categorized changes -release_output_template = '''{% set breaking_with_desc = all_notes|selectattr('category', 'equalto', '💥 Breaking Changes')|selectattr('description')|list %} -{% if breaking_with_desc|length > 0 %} -
## 💥 Breaking Changes -{% for note in breaking_with_desc %} -
### {{ note.title }} -{{ note.description }} -{% if note.url %}See {{ note.url }} for details.{% endif %} - -{% endfor %} -{% endif %} -{% set migration_notes = all_notes|selectattr('migration_notes')|list %} -{% if migration_notes|length > 0 %} -
## 🔄 Migrations -{% for note in migration_notes %} -
### {{ note.title }} -{{ note.migration_notes }} -{% if note.url and note.short_repo_link %}See [{{ note.short_repo_link }}]({{ note.url }}) for details.{% elif note.url %}See {{ note.url }} for details.{% endif %} - -{% endfor %} -{% endif %} -{% set non_breaking_with_desc = all_notes|rejectattr('category', 'equalto', '💥 Breaking Changes')|selectattr('description')|list %} -{% if non_breaking_with_desc|length > 0 %} -
## 📝 Highlights -{% for note in non_breaking_with_desc %} -
### {{ note.title }} -{{ note.description }} -{% if note.url and note.short_repo_link %}See [{{ note.short_repo_link }}]({{ note.url }}) for details.{% elif note.url %}See {{ note.url }} for details.{% endif %} - -{% endfor %} -{% endif %} -
## 📋 All Changes -{% for category in categories %} -
### {{ category.name }} -{% for note in category.notes %} -{% if loop.first %}
{% endif %}{{ render_entry(note) }}
-{% endfor %} -{% endfor %}''' - -# ============================================================================= -# Output Configuration -# ============================================================================= - -[[release_notes.categories]] -name = "💥 Breaking Changes" -labels = ["breaking-change", "breaking"] -order = 1 -alias = "breaking" - -[[release_notes.categories]] -name = "🚀 Features" -labels = ["feature", "enhancement", "feat"] -order = 2 -alias = "features" - -[[release_notes.categories]] -name = "🛠 Bug Fixes" -labels = ["bug", "fix", "bugfix", "hotfix"] -order = 3 -alias = "bugfixes" - -[[release_notes.categories]] -name = "📖 Documentation" -labels = ["docs", "documentation"] -order = 4 -alias = "docs" - -[[release_notes.categories]] -name = "🛡 Security Updates" -labels = ["security"] -order = 5 -alias = "security" - -[[release_notes.categories]] -name = "Other" -labels = [] -order = 99 -alias = "other" - -# ============================================================================= -# PR Code Generation Templates -# ============================================================================= -# Configure multiple code generation templates. Each template generates a separate -# output file from the release notes data. -# -# NOTE: This config has no templates configured. -# Add [[output.pr_code.templates]] entries to generate output files. -# -# Template structure: -# [[output.pr_code.templates]] -# output_template = "Jinja2 template string" -# output_path = "path/to/output.md" -# -# Available variables: -# - {{ version }}, {{ major }}, {{ minor }}, {{ patch }}: Version components -# - {{ title }}: Rendered release title -# - {{ year }}: Current year -# - {{ categories }}: List of category dicts with 'name', 'alias', 'notes' -# - {{ all_notes }}: Flat list of all note dicts -# - {{ render_entry(note) }}: Function to render a note using entry_template -# - {{ render_release_notes() }}: Function to render the default GitHub release notes -# -# Example: -# [[output.pr_code.templates]] -# output_template = '''--- -# id: release-{{version}} -# title: {{title}} -# --- -# {{ render_release_notes() }}''' -# output_path = "docs/releases/{{version}}.md" - -# ============================================================================= -# PR Code Generation Templates -# ============================================================================= -# Configure multiple code generation templates. Each template generates a separate -# output file from the release notes data. -# -# You can have multiple [[output.pr_code.templates]] entries to generate different outputs -# (e.g., Docusaurus docs, CHANGELOG.md, custom formats). - -[output.pr_code] -# DISABLED / UNUSED HERE -# [[output.pr_code.templates]] -# output_template: Jinja2 template for the output file content -# This is a POWERFUL template that gives you complete control over the output -# structure. Use Jinja2 syntax including conditionals, loops, filters, and all -# available variables. -# -# WHEN TO USE: -# - Generate Docusaurus documentation with frontmatter -# - Create custom changelog formats -# - Generate multiple output files from the same release data -# - Wrap release notes with additional metadata or formatting -# -# IMPORTANT: HTML-like behavior for whitespace -# - Multiple spaces/tabs collapse to single space (like HTML) -# - Line breaks: Use
or
for explicit line breaks in output -# - Non-breaking spaces: Use   for spaces that won't collapse -# - This allows multi-line templates for readability while controlling output -# -# Available variables: -# - {{ version }} : Version string (e.g., "1.2.3") -# - {{ major }} : Major version number (e.g., "1") -# - {{ minor }} : Minor version number (e.g., "2") -# - {{ patch }} : Patch version number (e.g., "3") -# - {{ title }} : Rendered release title (from title_template) -# - {{ year }} : Current year (e.g., "2025") -# - {{ categories }} : List of category dicts with 'name', 'alias', 'notes' -# - {{ all_notes }} : Flat list of all note dicts (across categories) -# - {{ render_entry(note) }} : Function to render a note using entry_template -# - {{ render_release_notes() }} : Function to render the default GitHub release notes -# -# Each note dict in all_notes or category.notes contains: -# - title, url (prioritizes issue_url over pr_url), issue_url, pr_url -# - short_link (#123), short_repo_link (meta#123) -# - pr_numbers, commit_shas, labels, issue_key, category -# - description, migration_notes (processed, may be None) -# - authors (list of author dicts with all fields) -# -# Template examples: -# -# 1. Docusaurus with frontmatter (DEFAULT - wraps GitHub release notes): -# output_template = '''--- -# id: release-{{version}} -# title: {{title}} -# --- -# # Release {{version}} -# -# {{ render_release_notes() }}
''' -# -# 2. Simple CHANGELOG (just release notes): -# output_template = '''{{ render_release_notes() }}''' -# -# 3. Custom category-based layout: -# output_template = '''# {{ title }} -# -# {% for category in categories %} -# ## {{ category.name }} -# {% for note in category.notes %} -# {{ render_entry(note) }} -# {% endfor %} -# {% endfor %}''' -# -# 4. Flat list without categories: -# output_template = '''# {{ title }} -# -# {% for note in all_notes %} -# {{ render_entry(note) }} -# {% endfor %}''' -# -# Default: Docusaurus template with frontmatter and default release notes -## output_template = '''--- -## id: release-{{version}} -## title: {{title}} -## --- -## -## # Release {{version}} -## -## {{ render_release_notes() }}''' - -# output_path: Path template for the output file (Jinja2 syntax) -# This file will be created/updated when using the generate and push commands. -# -# Available variables for path substitution: -# - {{version}}: Full version string (e.g., "1.2.3", "2.0.0-rc.1") -# - {{major}}: Major version number only (e.g., "1") -# - {{minor}}: Minor version number only (e.g., "2") -# - {{patch}}: Patch version number only (e.g., "3") -# -# Path template examples: -# - "CHANGELOG.md": Single changelog file (overwrites) -# - "docs/releases/{{version}}.md": Separate file per version -# - "docs/docusaurus/docs/releases/release-{{major}}.{{minor}}/release-{{major}}.{{minor}}.{{patch}}.md": Organized by version -# -# Default example: Docusaurus versioned docs -## output_path = "docs/docusaurus/docs/releases/release-{{major}}.{{minor}}/release-{{major}}.{{minor}}.{{patch}}.md" -# release_version_policy: Policy for generating documentation files for release candidates -# -# This controls how documentation files are generated when working with release candidates (RC versions). -# It only affects this template's output_path generation, NOT GitHub release notes. -# -# Valid values: -# - "final-only" (DEFAULT): Generate documentation as if it were the final version -# * RC documentation files use final version name (e.g., 11.0.0.md for 11.0.0-rc.1) -# * Content compares against previous final version (e.g., 10.x.x) -# * Each RC overwrites the same file, building up cumulative changelog -# * Final version generates to the same file with complete changelog -# * GitHub release notes still use standard comparison (RC.1 vs RC.0) -# -# - "include-rcs": Generate separate documentation files for each RC -# * RC documentation files include RC suffix (e.g., 11.0.0-rc.1.md) -# * Content uses standard version comparison (RC.1 vs RC.0 or previous final) -# * Each RC generates a separate file -# * Final version generates to its own file (11.0.0.md) -# * GitHub release notes use standard comparison -# -# Use Cases: -# - "final-only": Best for Docusaurus/versioned docs where you want one file per version -# that gets updated as RCs progress to final. This ensures documentation -# always shows the complete changelog for the upcoming release. -# -# - "include-rcs": Best when you want to document each RC separately, keeping history -# of what changed in each release candidate. Useful for detailed -# release tracking or when RCs are deployed to different environments. -# -# Example with "final-only" for version 11.0.0: -# - Generate 11.0.0-rc.0: -# * Doc file: docs/releases/11.0.0.md (compares 10.5.0 → 11.0.0-rc.0) -# * GitHub release: 11.0.0-rc.0 (compares 10.5.0 → 11.0.0-rc.0) -# - Generate 11.0.0-rc.1: -# * Doc file: docs/releases/11.0.0.md (compares 10.5.0 → 11.0.0-rc.1, OVERWRITES rc.0 docs) -# * GitHub release: 11.0.0-rc.1 (compares 11.0.0-rc.0 → 11.0.0-rc.1) -# - Generate 11.0.0: -# * Doc file: docs/releases/11.0.0.md (compares 10.5.0 → 11.0.0, OVERWRITES rc.1 docs) -# * GitHub release: 11.0.0 (compares 10.5.0 → 11.0.0, complete changelog) -# -# Example with "include-rcs" for version 11.0.0: -# - Generate 11.0.0-rc.0: -# * Doc file: docs/releases/11.0.0-rc.0.md (compares 10.5.0 → 11.0.0-rc.0) -# * GitHub release: 11.0.0-rc.0 (compares 10.5.0 → 11.0.0-rc.0) -# - Generate 11.0.0-rc.1: -# * Doc file: docs/releases/11.0.0-rc.1.md (compares 11.0.0-rc.0 → 11.0.0-rc.1) -# * GitHub release: 11.0.0-rc.1 (compares 11.0.0-rc.0 → 11.0.0-rc.1) -# - Generate 11.0.0: -# * Doc file: docs/releases/11.0.0.md (compares 10.5.0 → 11.0.0) -# * GitHub release: 11.0.0 (compares 10.5.0 → 11.0.0) -# -# Default: "final-only" -## release_version_policy = "final-only" - -# ============================================================================= -# Release Notes Formatting and Content -# ============================================================================= - -[output] -# draft_output_path: Path template for draft release notes (generate command, Jinja2 syntax) -# This is where 'generate' command saves files by default (when --output not specified) -# Files are saved here for review/editing before publishing to GitHub -# -# Available variables: -# - {{code_repo}}: Sanitized code repository name (e.g., "sequentech-step") -# - {{version}}: Full version string -# - {{major}}: Major version number -# - {{minor}}: Minor version number -# - {{patch}}: Patch version number -# - {{output_file_type}}: Type of output file ("release" or "doc") -# -# Examples: -# - ".release_tool_cache/draft-releases/{{code_repo}}/{{version}}-{{output_file_type}}.md": Organized by repo and version (DEFAULT) -# - "drafts/{{major}}.{{minor}}.{{patch}}-{{output_file_type}}.md": Simple draft folder -# - "/tmp/releases/{{code_repo}}-{{version}}-{{output_file_type}}.md": Temporary location -# -# Default: ".release_tool_cache/draft-releases/{{code_repo}}/{{version}}-{{output_file_type}}.md" -draft_output_path = ".release_tool_cache/draft-releases/{{code_repo}}/{{version}}-{{output_file_type}}.md" - -# assets_path: Path template for downloaded media assets (images, videos, Jinja2 syntax) -# Images and videos referenced in issue descriptions will be downloaded here -# and references will be updated to use local paths in the release notes -# This is useful for Docusaurus and other static site generators -# -# Available variables (same as output_path): -# - {{version}}: Full version string -# - {{major}}: Major version number -# - {{minor}}: Minor version number -# - {{patch}}: Patch version number -# -# Path must be relative to output_path for correct markdown references -# Examples: -# - "docs/releases/assets/{{version}}": Organized by version -# - "static/img/releases/{{major}}.{{minor}}": Shared across patches -# - "assets/{{version}}": Simple structure -# -# Default: "docs/releases/assets/{{version}}" -assets_path = "docs/releases/{{version}}/assets/" - -# download_media: Download images and videos from issue descriptions -# When true: Downloads media files and updates references to local paths -# When false: Keeps original URLs in release notes -# Default: true -# RECOMMENDED: true for static sites (Docusaurus), false for GitHub releases -download_media = true - -# create_github_release: Automatically create a GitHub release -# When true: Uploads release notes to GitHub Releases -# When false: Only generates markdown (no upload) -# Default: true -# CLI override: --release / --no-release -# SECURITY: Requires GitHub token with repo write permissions -create_github_release = true - -# create_pr: Automatically create a PR with the release notes file -# When true: Creates a PR to add/update the release notes file -# When false: No PR is created -# Requires: output_path to be configured -# Default: true -# CLI override: --pr / --no-pr -create_pr = true - -# release_mode: Default release mode for GitHub releases -# Options: -# - "draft": Releases are created as drafts (unpublished) -# - "published": Releases are published immediately -# Default: "draft" -# CLI override: --release-mode draft|published -# Use case: Set to "draft" if you want to review releases before publishing -release_mode = "draft" - -# prerelease: Mark GitHub releases as prereleases -# Options: -# - "auto": Auto-detect from version (e.g., "1.0.0-rc.1" → prerelease, "1.0.0" → stable) -# - true: Always mark as prerelease -# - false: Always mark as stable/final -# Default: "auto" -# CLI override: --prerelease auto|true|false -# Use cases: -# - "auto": Most flexible, automatically handles RCs and stable releases -# - true: If you typically create beta/RC releases and want to be explicit -# - false: For projects that only do stable releases -prerelease = "false" - -# create_issue: Whether to create a tracking issue for the release -# When true, a GitHub issue will be created automatically and PR templates can use -# {{issue_repo}}, {{issue_number}}, and {{issue_link}} variables -# Default: true -# Use case: Set to false if you don't want to track releases with GitHub issues -create_issue = true - -# ============================================================================= -# Release Tracking Issue Templates (for create_issue) -# ============================================================================= -[output.issue_templates] -# title_template: Template for the issue title -# Available variables: -# - {{version}}: Full version string (e.g., "1.2.3") -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{num_changes}}, {{num_categories}}: Release notes statistics -# -# Examples: -# - "Release {{version}}": Simple format (DEFAULT) -# - "Release v{{version}} - {{num_changes}} changes": With stats -# -# Default: "✨ Prepare Release {{version}}" -title_template = "✨ Prepare Release {{version}}" - -# body_template: Template for the issue description (supports multi-line) -# Available variables: -# - {{version}}: Full version string (e.g., "1.2.3") -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{num_changes}}, {{num_categories}}: Release notes statistics -# - {{pr_link}}: Link to the release notes PR (will be populated after PR creation) -# - {{issue_repo_name}}: Short name of issues repo (e.g. "meta" from "sequentech/meta") -# -# Default: Release preparation checklist based on step's .github release template -body_template = '''### DevOps Tasks - -- [ ] Github release notes: correct and complete -- [ ] Docusaurus release notes: correct and complete -- [ ] BEYOND-PR-HERE for a new default tenant/election-event template and any new other changes (branch should be `release/{{major}}.{{minor}}`) -- [ ] GITOPS-PR-HERE for a new default tenant/election-event template and any new other changes (branch should be `release/{{major}}.{{minor}}`) -- [ ] Request in Environments spreadsheet to get deployment approval by environment owners - -NOTE: Please also update deployment status when a release is deployed in an environment. - -### QA Flight List - -- [ ] Deploy in `dev` -- [ ] Positive Test in `dev` -- [ ] Deploy in `qa` -- [ ] Positive Test in `qa` - -### PRs - -- {{pr_link}}''' - -# labels: Labels to apply to the release tracking issue -# Default: ["release", "devops", "infrastructure"] -labels = ["release", "devops", "infrastructure"] - -# assignee: GitHub username to assign the issue to -# If not specified (or commented out), the issue is assigned to the user -# authenticated with the GitHub token (the one running the tool). -# Set this if you want to assign the release issue to a specific person or bot. -# Example: "johndoe" -assignee = "edulix" - -# project_id: GitHub Project V2 Number to add the issue to -# This allows automatically adding the release issue to a GitHub Project board. -# The value should be the project NUMBER found in the URL (e.g. 1 for .../projects/1), -# NOT the Node ID (PVT_...). -# NOTE: This requires the GitHub token to have 'project' scope (for PATs) or -# appropriate permissions (for GitHub Apps). -# Example: "1" -project_id = "1" - -# project_status: Status to set in the GitHub Project -# Sets the value of the "Status" field in the project board. -# The value must EXACTLY match a valid status option in your project (case-sensitive). -# This setting is ignored if project_id is not set. -# Common values: "Todo", "In Progress", "Backlog", "Ready" -# Example: "Todo" -project_status = "In progress" - -# project_fields: Custom fields to set in the GitHub Project -# Allows setting additional metadata fields in the project board. -# This is a key-value map where: -# - Key: The exact name of the field in the project (e.g., "Priority", "Sprint") -# - Value: The value to set. Supports: -# * Text/Number/Date fields: The value as a string -# * Single Select fields: The option name (case-insensitive) -# * Iteration fields: The iteration name OR "@current" to automatically select the active iteration -# This setting is ignored if project_id is not set. -# Example: { "Priority" = "High", "Estimate" = "3", "Iteration" = "@current" } -project_fields = { "Team" = "Product", "Estimate" = "3", "Iteration" = "@current" } - -# type: Issue type to set -# Specifies the type of the issue (e.g., "Task", "Bug", "Feature"). -# This is typically mapped to a label with the same name. -# Example: "Task" -type = "Task" - -# milestone: Milestone to assign the issue to -# Specifies the name of the GitHub milestone to assign. -# The milestone must exist in the repository. -# -# Available variables: -# - {{version}}: Full version string (e.g., "1.2.3") -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{year}}: Current year (e.g., "2025") -# - {{quarter_uppercase}}: Current quarter (e.g., "Q4") -# -# Examples: -# - "{{year}}_{{quarter_uppercase}}": Time-based (DEFAULT) -> "2025_Q4" -# - "v{{major}}.{{minor}}": Version-based -> "v1.2" -# - "Release {{version}}": Full version -> "Release 1.2.3" -# -# Default: "{{year}}_{{quarter_uppercase}}" -milestone = "{{year}}_{{quarter_uppercase}}" - -# ============================================================================= -# Pull Request Templates (for create_pr) -# ============================================================================= -[output.pr_templates] -# ALL TEMPLATES USE JINJA2 SYNTAX: {{ variable_name }} -# -# branch_template: Template for the PR branch name -# Available variables (always): -# - {{version}}: Full version string (e.g., "1.2.3") -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{code_repo}}: Sanitized code repository name (e.g., "sequentech-step") -# - {{issue_repo}}: Issues repository name (e.g., "sequentech/meta") -# - {{issue_repo_name}}: Short name of issues repo (e.g. "meta" from "sequentech/meta") -# - {{target_branch}}: Target branch for PR -# -# Available variables (only when create_issue=true and issue was created): -# - {{issue_number}}: Auto-generated issue number -# - {{issue_link}}: Auto-generated issue URL -# -# Examples: -# - "release-notes-{{version}}": Simple format -# - "docs/{{issue_repo_name}}-{{issue_number}}/{{target_branch}}": With issue tracking (DEFAULT) -# - "docs/release-{{major}}.{{minor}}.{{patch}}": Structured branch -# - "chore/update-changelog-{{version}}": With prefix -# -# Default: "docs/{{issue_repo_name}}-{{issue_number}}/{{target_branch}}" -branch_template = "docs/{{issue_repo_name}}-{{issue_number}}/{{target_branch}}" - -# title_template: Template for the PR title -# Available variables (always): -# - {{version}}: Full version string -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{num_changes}}: Number of changes in release notes -# - {{num_categories}}: Number of categories -# - {{code_repo}}, {{issue_repo}}: Repository names -# -# Available variables (only when create_issue=true and issue was created): -# - {{issue_number}}, {{issue_link}}: Issue information -# -# Examples: -# - "Release notes for {{version}}": Simple title (DEFAULT) -# - "docs: Add release notes for v{{version}}": Conventional commits -# - "Release {{version}} with {{num_changes}} changes": With counts -# -# Default: "Release notes for {{version}}" -title_template = "Release notes for {{version}}" - -# body_template: Template for the PR description (supports multi-line) -# Available variables: -# - {{version}}: Full version string -# - {{major}}, {{minor}}, {{patch}}: Version components -# - {{num_changes}}: Number of changes in release notes -# - {{num_categories}}: Number of categories -# - {{code_repo}}: Sanitized code repository name -# - {{issue_repo}}: Issues repository name -# - {{issue_repo_name}}: Short name of issues repo -# - {{target_branch}}: Target branch for PR -# -# Available variables (only when create_issue=true and issue was created): -# - {{issue_number}}: Auto-generated issue number -# - {{issue_link}}: Auto-generated issue URL -# -# Examples: -# - Simple: -# body_template = "Automated release notes for version {{version}}." -# -# - With issue tracking (DEFAULT) - use triple quotes for multi-line: -# body_template = '''Parent issue: {{issue_link}} -# -# Automated release notes for version {{version}}. -# -# ## Summary -# This PR adds release notes for {{version}} with {{num_changes}} changes across {{num_categories}} categories.''' -# -# Default: Multi-line with issue link and summary -body_template = '''Parent issue: {{issue_link}} - -Automated release notes for version {{version}}. - -## Summary -This PR adds release notes for {{version}} with {{num_changes}} changes across {{num_categories}} categories.''' - -# ============================================================================= -# End of Configuration -# =============================================================================