Skip to content

Conversation

ogajduse
Copy link
Member

Summary

  • Automate Hammer CLI release notes integration in scripts/release_notes.rb
  • Add configurable category mapping system for maintainable transformations
  • Eliminate manual copy-paste work for Hammer CLI components during releases

Background

Manual integration of Hammer CLI release notes into Foreman documentation is time-consuming and error-prone during releases. This addresses theforeman/theforeman-rel-eng#514 by automating the process through the existing release_notes.rb script.

Changes Made

Core Functionality

  • Extended release_notes.rb to fetch both hammer-cli and hammer-cli-foreman release notes from Redmine
  • Added support for version prefixes (e.g., hammer-cli-3.16.0, hammer-cli-foreman-3.16.0)
  • Integrated Hammer CLI sections into the existing release notes workflow

Configurable Category Mapping System

  • Replaced hardcoded category transformations with configurable CATEGORY_MAPPINGS
  • Added support for:
    • Merge mappings: Combine multiple source categories into target categories
    • Project-specific transformations: Apply different rules based on component type
    • Regex-based renaming: Flexible pattern matching for category names

Output Format

The script now automatically generates properly formatted Hammer CLI sections:

+#### Hammer CLI - Hammer core
+* Translated paths for replaced_by fields may differ from actual path ([#38427](https://projects.theforeman.org/issues/38427))
+
+#### Hammer CLI - Foreman - Compute resources
+* Remove Ovirt from Hammer ([#38294](https://projects.theforeman.org/issues/38294))
+
+#### Hammer CLI - Foreman - Users and roles
+* LDAP group membership ([#38611](https://projects.theforeman.org/issues/38611))

Usage

ruby scripts/release_notes.rb foreman 3.16.0

Now automatically includes Hammer CLI and Hammer CLI - Foreman sections alongside Foreman release notes.

Benefits

  • Eliminates manual work: No more copy-paste from Hammer CLI repositories
  • Maintains consistency: Automated formatting ensures uniform output
  • Easily extensible: New category mappings can be added without code changes

🤖 Generated with Claude Code

## Background
Manual integration of Hammer CLI release notes into Foreman documentation
is time-consuming and error-prone. This addresses theforeman/theforeman-rel-eng#514
by automating the process through the existing release_notes.rb script.

## Expected Steps:
* Extend release_notes.rb to fetch Hammer CLI and Hammer CLI - Foreman release notes
* Add configurable category mapping system for maintainable transformations
* Generate properly formatted sections matching existing manual structure
* Maintain human oversight through script output review

## Definition of Done:
* Script automatically generates Hammer CLI and Hammer CLI - Foreman sections
* Category mappings are configurable and easily extensible
* Output format matches existing theforeman.org manual structure
* No manual copy-paste work required for Hammer CLI components

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@ogajduse ogajduse requested a review from a team August 27, 2025 12:26
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks very complex and would suggest to start fresh. My recommendation would be to take https://github.com/theforeman/foreman-documentation/blob/master/guides/doc-Release_Notes/redmine_release_notes as a base. Then work on expanding that.

The first thing I would try is the trick I suggest inline with repeating v[cf_12][] multiple time, once for each release you want to include.

It also already cleaner where category_from_issue is already the method to extract the category from an issue. I think that's a better base then the complex mapping here.

Once you have the version in foreman-documentation working then I'd suggest to replace the script in this repo with a version that spits out markdown instead of asciidoc.

rescue StandardError => e
puts "Error getting version list from #{url}: #{e}"
exit 1
return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should still exit if it fails. It may not be very clean, but it's a simple script and it's good enough error handling.

Suggested change
return nil
exit 1

].freeze

# Category mappings and transformations
CATEGORY_MAPPINGS = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is too complex. Why don't you simplify this to various separate constants?

Comment on lines +37 to +40
# Rename categories - simple string replacements using regex patterns
rename: {
/^Hammer CLI$/ => 'Hammer CLI', # Keep as-is for base hammer-cli
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of this noop rename? Feels like this can just be dropped.

Comment on lines +103 to +111
CATEGORY_MAPPINGS[:merge].each do |target_category, source_categories|
grouped_issues[target_category] ||= [] # Initialize if doesn't exist
source_categories.each do |source_category|
if grouped_issues.key?(source_category)
# Move issues from source to target category and remove source
grouped_issues[target_category] += grouped_issues.delete(source_category)
end
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels way overengineered. The previous code was easier to understand IMHO. Now you have ~15 lines of code for what used to be 2 lines.

Comment on lines +129 to +137
# Step 3: Apply general rename mappings
new_grouped_issues = {}
grouped_issues.each do |category, category_issues|
new_category = category
CATEGORY_MAPPINGS[:rename].each do |pattern, replacement|
new_category = new_category.gsub(pattern, replacement)
end
new_grouped_issues[new_category] = category_issues
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole renaming isn't used so I think this can be dropped

Suggested change
# Step 3: Apply general rename mappings
new_grouped_issues = {}
grouped_issues.each do |category, category_issues|
new_category = category
CATEGORY_MAPPINGS[:rename].each do |pattern, replacement|
new_category = new_category.gsub(pattern, replacement)
end
new_grouped_issues[new_category] = category_issues
end

Comment on lines +42 to +47
# Project-specific category transformations
project_specific: {
'hammer-cli-foreman-' => {
/^Hammer CLI/ => 'Hammer CLI - Foreman'
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This took me a long time to figure out and again, IMHO a bit too complex.

generate_release_notes_for_project(project_config[:project], @current_release_name, project_config[:version_prefix])
end

puts "*A full list of changes in #{@current_release_name} is available via [Redmine](https://projects.theforeman.org/issues?set_filter=1&sort=id%3Adesc&status_id=closed&f[]=cf_12&op[cf_12]=%3D&v[cf_12]=#{@current_release_id})*"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer true because you also need to include the Hammer releases.

'v[cf_12][]' => @current_release_id,
'f[]' => 'cf_12', # Filter by custom field 12 (Fix version)
'op[cf_12]' => '=', # Operator: equals
'v[cf_12][]' => release_id, # Value: the release ID we want
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can repeat this parameter to gather the issues for multiple releases in a single API call. I think you can just change params to an array of arrays and repeat v[cf12][] for each release you want to include.


grouped_issues = gather_issues.group_by { |issue| "#{issue['project']['name']}#{ ' - ' + issue['category']['name'] if issue.key?('category') }" }
# Sort categories alphabetically
grouped_issues = Hash[ grouped_issues.sort_by { |key, val| key } ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this existed before, but this can be done easier in current Ruby (probably couldn't when it was written). The version in foreman-documentation already does this.

Suggested change
grouped_issues = Hash[ grouped_issues.sort_by { |key, val| key } ]
grouped_issues = grouped_issues.sort

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants