Skip to content

Commit bfc6392

Browse files
committed
Takes from the skill and puts it into the action
1 parent 1c21a6a commit bfc6392

2 files changed

Lines changed: 107 additions & 26 deletions

File tree

.claude/skills/rubocop-update/scripts/parse_changelog.rb

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
opts.banner = "Usage: parse_changelog.rb [options]"
88
opts.on("--old VERSION", "Old version (e.g., 1.84.0)") { |v| options[:old] = v }
99
opts.on("--new VERSION", "New version (e.g., 1.86.1)") { |v| options[:new] = v }
10+
opts.on("--no-recommendations", "Skip recommendation and rationale columns") { options[:no_recommendations] = true }
1011
end.parse!
1112

1213
unless options[:old] && options[:new]
@@ -47,33 +48,60 @@ def extract_cops(lines, section_header)
4748
# 2. * [#123](url): Add new `Cop/Name` cop.
4849
# 3. * **Cop/Name**: Description ([#123](url))
4950

50-
if line =~ /^\s*\*\s+.*`([^`]+)`.*\[#(\d+)\]\(([^)]+)\):?\s*(.*)$/
51-
cops << { name: $1, pr_id: $2, pr_url: $3, description: $4.strip.gsub(/\.$/, '') }
52-
elsif line =~ /^\s*\*\s+.*`([^`]+)`.*:?\s*(.*)\s+\(\[#(\d+)\]\(([^)]+)\)\)$/
53-
cops << { name: $1, pr_id: $3, pr_url: $4, description: $2.strip.gsub(/\.$/, '') }
54-
elsif line =~ /^\s*\*\s+\[#(\d+)\]\(([^)]+)\):\s+.*`([^`]+)`\s*(.*)$/
55-
cops << { name: $3, pr_id: $1, pr_url: $2, description: $4.strip.gsub(/\.$/, '') }
51+
# Regex 1: * [#123](url): Add new `Cop/Name` cop. ([@user][])
52+
# Regex 2: * Add new `Cop/Name` cop. ([#123](url))
53+
# Regex 3: * **Cop/Name**: Description ([#123](url))
54+
55+
# Regex 1: * [#123](url): Add new `Cop/Name` cop. ([@user][])
56+
# Regex 2: * Add new `Cop/Name` cop. ([#123](url))
57+
# Regex 3: * **Cop/Name**: Description ([#123](url))
58+
59+
if line =~ /^\s*\*\s+\[#(\d+)\]\(([^)]+)\):\s+(.*)\s*`([^`]+)`.*$/
60+
pr_id, pr_url, desc, name = $1, $2, $3, $4
61+
elsif line =~ /^\s*\*\s+(.*)\s*`([^`]+)`.*\[#(\d+)\]\(([^)]+)\).*$/
62+
desc, name, pr_id, pr_url = $1, $2, $3, $4
5663
elsif line =~ /^\s*\*\s+\*\*([^*]+)\*\*:\s*(.*)\s+\(\[#(\d+)\]\(([^)]+)\)\)$/
57-
cops << { name: $1, pr_id: $3, pr_url: $4, description: $2.strip.gsub(/\.$/, '') }
64+
name, desc, pr_id, pr_url = $1, $2, $3, $4
65+
else
66+
next
5867
end
68+
69+
# Clean up description
70+
desc = desc.to_s.strip
71+
desc = desc.gsub(/\s*\(\[@[\w-]*\]\[\]\)$/, '') # Strip ([@user][])
72+
desc = desc.gsub(/\s*cop\.?$/, '') # Strip " cop" at end
73+
desc = desc.gsub(/^\s*:?\s*/, '') # Strip leading colon/space
74+
desc = desc.strip
75+
desc = "New cop" if desc.empty?
76+
77+
cops << { name: name, pr_id: pr_id, pr_url: pr_url, description: desc.gsub(/\.$/, '') }
5978
end
6079
cops.uniq { |c| c[:name] }
6180
end
6281

6382
new_cops = extract_cops(relevant_lines, "New features")
6483
changed_cops = extract_cops(relevant_lines, "Changes")
6584

66-
def print_table(title, cops, column_name)
85+
def print_table(title, cops, column_name, options = {})
6786
return if cops.empty?
6887
puts "## #{title}"
6988
puts ""
7089
if title == "New cops"
71-
puts "| Cop | Description | Recommendation | Rationale | PR |"
72-
puts "|-----|-------------|----------------|-----------|-----|"
90+
if options[:no_recommendations]
91+
puts "| Cop | Description | PR |"
92+
puts "|-----|-------------|-----|"
93+
else
94+
puts "| Cop | Description | Recommendation | Rationale | PR |"
95+
puts "|-----|-------------|----------------|-----------|-----|"
96+
end
7397
cops.each do |cop|
7498
desc = cop[:description].empty? ? "No description provided" : cop[:description]
75-
# Placeholders for the agent to fill in
76-
puts "| `#{cop[:name]}` | #{desc} | {RECOMMENDATION} | {RATIONALE} | [##{cop[:pr_id]}](#{cop[:pr_url]}) |"
99+
if options[:no_recommendations]
100+
puts "| `#{cop[:name]}` | #{desc} | [##{cop[:pr_id]}](#{cop[:pr_url]}) |"
101+
else
102+
# Placeholders for the agent to fill in
103+
puts "| `#{cop[:name]}` | #{desc} | {RECOMMENDATION} | {RATIONALE} | [##{cop[:pr_id]}](#{cop[:pr_url]}) |"
104+
end
77105
end
78106
else
79107
puts "| Cop | #{column_name} | PR |"
@@ -86,5 +114,5 @@ def print_table(title, cops, column_name)
86114
puts ""
87115
end
88116

89-
print_table("New cops", new_cops, "Description")
90-
print_table("Changed cops", changed_cops, "Change")
117+
print_table("New cops", new_cops, "Description", options)
118+
print_table("Changed cops", changed_cops, "Change", options)

.github/workflows/update.yml

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,83 @@ jobs:
2525
- name: Get Outdated
2626
id: outdated
2727
run: |
28-
eval "$(bundle outdated rubocop rubocop-performance |
29-
grep rubocop |
30-
awk '{print "echo \"::set-output name="$1"_OLD::"$2"\"; echo \"::set-output name="$1"_NEW::"$3"\";"}' - )";
28+
# Use bundle outdated and parse versions
29+
# Format: gem-name (newest 1.2.3, installed 1.2.2)
30+
OUTDATED=$(bundle outdated rubocop standard-performance --strict || true)
31+
echo "$OUTDATED"
32+
33+
RUBOCOP_OLD=$(echo "$OUTDATED" | grep "rubocop " | sed -E 's/.*installed ([0-9.]+).*/\1/')
34+
RUBOCOP_NEW=$(echo "$OUTDATED" | grep "rubocop " | sed -E 's/.*newest ([0-9.]+).*/\1/')
35+
PERF_OLD=$(echo "$OUTDATED" | grep "standard-performance " | sed -E 's/.*installed ([0-9.]+).*/\1/')
36+
PERF_NEW=$(echo "$OUTDATED" | grep "standard-performance " | sed -E 's/.*newest ([0-9.]+).*/\1/')
37+
38+
echo "rubocop_old=$RUBOCOP_OLD" >> $GITHUB_OUTPUT
39+
echo "rubocop_new=$RUBOCOP_NEW" >> $GITHUB_OUTPUT
40+
echo "perf_old=$PERF_OLD" >> $GITHUB_OUTPUT
41+
echo "perf_new=$PERF_NEW" >> $GITHUB_OUTPUT
3142
- name: Update Changelog
43+
if: steps.outdated.outputs.rubocop_new != '' || steps.outdated.outputs.perf_new != ''
3244
run: |
33-
eval "$(bundle outdated rubocop rubocop-performance |
34-
grep rubocop |
35-
awk '{print "sed -i \"2i* Update "$1" from "$2" to ["$3"](https://github.com/rubocop/"$1"/releases/tag/v"$3")\" CHANGELOG.md"}' - )";
36-
sed -i '2i\\n## Unreleased\n' CHANGELOG.md;
45+
if [ -n "${{ steps.outdated.outputs.rubocop_new }}" ]; then
46+
sed -i "2i* Update rubocop from ${{ steps.outdated.outputs.rubocop_old }} to [${{ steps.outdated.outputs.rubocop_new }}](https://github.com/rubocop/rubocop/releases/tag/v${{ steps.outdated.outputs.rubocop_new }})" CHANGELOG.md
47+
fi
48+
if [ -n "${{ steps.outdated.outputs.perf_new }}" ]; then
49+
sed -i "2i* Update standard-performance from ${{ steps.outdated.outputs.perf_old }} to [${{ steps.outdated.outputs.perf_new }}](https://github.com/standardrb/standard-performance/releases/tag/v${{ steps.outdated.outputs.perf_new }})" CHANGELOG.md
50+
fi
51+
sed -i '2i\\n## Unreleased\n' CHANGELOG.md
3752
- name: Update Gemspec
53+
if: steps.outdated.outputs.rubocop_new != '' || steps.outdated.outputs.perf_new != ''
3854
run: |
39-
eval "$(bundle outdated rubocop rubocop-performance |
40-
grep rubocop |
41-
awk '{print "sed -i /\"" $1 "\"/s/" $2 "/" $3 "/ standard.gemspec"}' - )"
55+
if [ -n "${{ steps.outdated.outputs.rubocop_new }}" ]; then
56+
# Update rubocop constraint to exactly the new version for patch/minor, but we usually want ~> MAJOR.MINOR.0
57+
# standard.gemspec has: spec.add_dependency "rubocop", "~> 1.84.0"
58+
NEW_VERSION="${{ steps.outdated.outputs.rubocop_new }}"
59+
# Extract MAJOR.MINOR.0
60+
BASE_VERSION=$(echo $NEW_VERSION | cut -d. -f1,2).0
61+
sed -i "s/\"rubocop\", \"~> [0-9.]*\"/\"rubocop\", \"~> $BASE_VERSION\"/" standard.gemspec
62+
fi
63+
if [ -n "${{ steps.outdated.outputs.perf_new }}" ]; then
64+
NEW_VERSION="${{ steps.outdated.outputs.perf_new }}"
65+
# Extract MAJOR.MINOR
66+
BASE_VERSION=$(echo $NEW_VERSION | cut -d. -f1,2)
67+
sed -i "s/\"standard-performance\", \"~> [0-9.]*\"/\"standard-performance\", \"~> $BASE_VERSION\"/" standard.gemspec
68+
fi
4269
- name: Update Gemfile
43-
run: bundle update
70+
if: steps.outdated.outputs.rubocop_new != '' || steps.outdated.outputs.perf_new != ''
71+
run: bundle update rubocop standard-performance
72+
- name: Generate PR Body
73+
if: steps.outdated.outputs.rubocop_new != '' || steps.outdated.outputs.perf_new != ''
74+
run: |
75+
if [ -n "${{ steps.outdated.outputs.rubocop_new }}" ]; then
76+
echo "Updates RuboCop from ${{ steps.outdated.outputs.rubocop_old }} to ${{ steps.outdated.outputs.rubocop_new }}." > pr_body.md
77+
fi
78+
if [ -n "${{ steps.outdated.outputs.perf_new }}" ]; then
79+
if [ -f pr_body.md ]; then
80+
echo "Updates standard-performance to ${{ steps.outdated.outputs.perf_new }}." >> pr_body.md
81+
else
82+
echo "Updates standard-performance to ${{ steps.outdated.outputs.perf_new }}." > pr_body.md
83+
fi
84+
fi
85+
echo "" >> pr_body.md
86+
87+
if [ -n "${{ steps.outdated.outputs.rubocop_new }}" ]; then
88+
curl -s https://raw.githubusercontent.com/rubocop/rubocop/main/CHANGELOG.md | \
89+
ruby .claude/skills/rubocop-update/scripts/parse_changelog.rb \
90+
--old ${{ steps.outdated.outputs.rubocop_old }} \
91+
--new ${{ steps.outdated.outputs.rubocop_new }} \
92+
--no-recommendations >> pr_body.md
93+
fi
94+
95+
echo -e "\n---\n\nThe \`config/\` YAML files have not been updated for any of the above cops.\nTests are expected to fail until those configurations are added in a follow-up." >> pr_body.md
4496
- name: Get current date
4597
id: date
46-
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
98+
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
4799
- name: Create Pull Request
48100
uses: peter-evans/create-pull-request@v8
49101
with:
50102
reviewers: camilopayan
51103
commit-message: '[ ${{ steps.date.outputs.date }} ] - Update dependencies'
52104
title: '[ ${{ steps.date.outputs.date }} ] - Update dependencies'
105+
body-path: pr_body.md
53106
delete-branch: true
54107
branch: update-deps-${{ steps.date.outputs.date }}

0 commit comments

Comments
 (0)