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
92 changes: 10 additions & 82 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,6 @@ jobs:
fetch-depth: 0
token: ${{ secrets.RELEASE_TOKEN }}

- name: Determine release version
id: version
run: |
# Read current version from version.rb
CURRENT_VERSION=$(grep -oP "VERSION = '\K[^']+" lib/aspera/cli/version.rb)
echo "Current version in version.rb: $CURRENT_VERSION"

# Determine release version
if [ -n "${{ inputs.version }}" ]; then
RELEASE_VERSION="${{ inputs.version }}"
else
# Strip .pre suffix if present
RELEASE_VERSION="${CURRENT_VERSION%.pre}"
fi
echo "Release version: $RELEASE_VERSION"
echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT
echo "GEM_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV

# Determine next development version
if [ -n "${{ inputs.next_version }}" ]; then
NEXT_VERSION="${{ inputs.next_version }}"
else
# Parse version components and increment minor version
IFS='.' read -r MAJOR MINOR PATCH <<< "$RELEASE_VERSION"
NEXT_MINOR=$((MINOR + 1))
NEXT_VERSION="${MAJOR}.${NEXT_MINOR}.0"
fi
echo "Next development version: ${NEXT_VERSION}.pre"
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
Expand All @@ -75,58 +45,16 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Update version.rb for release
run: |
ruby build/lib/release_helper.rb update-version "${{ steps.version.outputs.release_version }}"
cat lib/aspera/cli/version.rb

- name: Update CHANGELOG.md for release
run: |
ruby build/lib/release_helper.rb update-changelog "${{ steps.version.outputs.release_version }}"

- name: Extract release notes
id: changelog
run: |
# Extract changelog and save to file for GitHub release
ruby build/lib/release_helper.rb extract-changelog > release_notes.md
cat release_notes.md

- name: Build documentation
run: |
mkdir -p pkg
bundle exec rake doc:build
env:
GEM_VERSION: ${{ steps.version.outputs.release_version }}

- name: Commit release changes
run: |
git add -A
git commit -m "Release v${{ steps.version.outputs.release_version }}"

- name: Create and push tag
run: |
git tag -a "v${{ steps.version.outputs.release_version }}" -m "Version ${{ steps.version.outputs.release_version }}"
git push origin "v${{ steps.version.outputs.release_version }}"

- name: Create GitHub Release
- name: Create release
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
gh release create "v${{ steps.version.outputs.release_version }}" \
--title "Aspera CLI v${{ steps.version.outputs.release_version }}" \
--notes-file release_notes.md

- name: Update version.rb for next development cycle
run: |
ruby build/lib/release_helper.rb update-version "${{ steps.version.outputs.next_version }}.pre"
cat lib/aspera/cli/version.rb

- name: Add new CHANGELOG section for next development cycle
run: |
ruby build/lib/release_helper.rb add-changelog-section "${{ steps.version.outputs.next_version }}"

- name: Commit next development version
run: |
git add -A
git commit -m "Prepare for next development cycle (${{ steps.version.outputs.next_version }}.pre)"
git push origin main
ARGS=""
if [ -n "${{ inputs.version }}" ]; then
ARGS="[${{ inputs.version }}"
if [ -n "${{ inputs.next_version }}" ]; then
ARGS="${ARGS},${{ inputs.next_version }}"
fi
ARGS="${ARGS}]"
fi
bundle exec rake "release:create${ARGS}"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
.idea
.vscode
.bundle
# temporary file generated during release workflow
/release_notes.md
108 changes: 0 additions & 108 deletions build/lib/release_helper.rb

This file was deleted.

175 changes: 175 additions & 0 deletions rakelib/release.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# frozen_string_literal: true

require 'date'
require_relative '../build/lib/paths'
require_relative '../build/lib/build_tools'
include BuildTools

# Release automation tasks
namespace :release do
CHANGELOG_FILE = Paths::TOP / 'CHANGELOG.md'
VERSION_FILE = Paths::TOP / 'lib/aspera/cli/version.rb'
RELEASE_NOTES_FILE = Paths::TOP / 'release_notes.md'

# Read current version from version.rb
def current_version
VERSION_FILE.read[/VERSION = '([^']+)'/, 1]
end

# Extract the latest changelog section (everything between first ## and second ##)
# Strips the version heading and release date lines
def extract_latest_changelog
content = CHANGELOG_FILE.read
# Match from first ## heading to the next ## heading (or end of file)
match = content.match(/^(## .+?)(?=^## |\z)/m)
return '' unless match

section = match[1].strip
# Remove the version heading (## X.Y.Z) and Released: line
section.sub(/\A## .+\n+Released: .+\n*/, '').strip
end

# Update CHANGELOG.md for release:
# - Replace version.pre with version
# - Replace date placeholder with today's date
def update_changelog_for_release(version)
content = CHANGELOG_FILE.read
today = Date.today.strftime('%Y-%m-%d')

# Replace the .pre version heading with release version
content.sub!(/^## #{Regexp.escape(version)}\.pre$/, "## #{version}")

# Replace the date placeholder
content.sub!(/^Released: \[Place date of release here\]$/, "Released: #{today}")

CHANGELOG_FILE.write(content)
end

# Add a new development section to CHANGELOG.md for the next version
def add_next_changelog_section(next_version)
content = CHANGELOG_FILE.read

new_section = <<~SECTION
## #{next_version}.pre

Released: [Place date of release here]

### New Features

### Issues Fixed

### Breaking Changes

SECTION

# Insert after the header comment block (after the markdownlint line)
content.sub!(
/^(# Changes \(Release notes\)\n\n<!-- markdownlint-configure-file .+? -->\n)\n/,
"\\1\n#{new_section}"
)

CHANGELOG_FILE.write(content)
end

# Update version.rb with a new version
def update_version_file(version)
content = VERSION_FILE.read
content.sub!(/VERSION = '[^']+'/, "VERSION = '#{version}'")
VERSION_FILE.write(content)
end

# Calculate next development version (increment minor version)
def calculate_next_version(release_version)
parts = release_version.split('.')
major, minor, _patch = parts[0].to_i, parts[1].to_i, parts[2].to_i
"#{major}.#{minor + 1}.0"
end

desc 'Extract latest changelog section to release_notes.md'
task :extract_changelog do
notes = extract_latest_changelog
RELEASE_NOTES_FILE.write(notes)
puts "Extracted changelog to #{RELEASE_NOTES_FILE}"
puts notes
end

desc 'Update CHANGELOG.md for release (remove .pre, set date)'
task :update_changelog, [:version] do |_t, args|
version = args[:version] || raise('Missing version argument')
update_changelog_for_release(version)
puts "Updated CHANGELOG.md for release #{version}"
end

desc 'Add new .pre section to CHANGELOG.md'
task :add_changelog_section, [:version] do |_t, args|
version = args[:version] || raise('Missing version argument')
add_next_changelog_section(version)
puts "Added new section for #{version}.pre to CHANGELOG.md"
end

desc 'Update version.rb'
task :update_version, [:version] do |_t, args|
version = args[:version] || raise('Missing version argument')
update_version_file(version)
puts "Updated version.rb to #{version}"
end

desc 'Show current version'
task :version do
puts current_version
end

desc 'Full release: update files, build docs, commit, tag, and create GitHub release'
task :create, [:version, :next_version] do |_t, args|
# Determine release version
release_version = args[:version] || current_version.sub(/\.pre$/, '')
next_version = args[:next_version] || calculate_next_version(release_version)

puts "Release version: #{release_version}"
puts "Next development version: #{next_version}.pre"

# Update version.rb for release
Rake::Task['release:update_version'].invoke(release_version)

# Update CHANGELOG.md for release
Rake::Task['release:update_changelog'].invoke(release_version)

# Extract release notes
Rake::Task['release:extract_changelog'].invoke

# Build documentation
ENV['GEM_VERSION'] = release_version
Rake::Task['doc:build'].invoke

# Build gem
Rake::Task['build'].invoke

# Git operations
run('git', 'add', '-A')
run('git', 'commit', '-m', "Release v#{release_version}")
run('git', 'tag', '-a', "v#{release_version}", '-m', "Version #{release_version}")
run('git', 'push', 'origin', "v#{release_version}")

# Create GitHub release with artifacts
pdf_file = Paths::RELEASE / "Manual-#{Aspera::Cli::Info::CMD_NAME}-#{release_version}.pdf"
gem_file = Paths::RELEASE / "#{Aspera::Cli::Info::GEM_NAME}-#{release_version}.gem"

run('gh', 'release', 'create', "v#{release_version}",
'--title', "Aspera CLI v#{release_version}",
'--notes-file', RELEASE_NOTES_FILE.to_s,
pdf_file.to_s,
gem_file.to_s)

# Prepare for next development cycle
Rake::Task['release:update_version'].reenable
Rake::Task['release:update_version'].invoke("#{next_version}.pre")

Rake::Task['release:add_changelog_section'].invoke(next_version)

run('git', 'add', '-A')
run('git', 'commit', '-m', "Prepare for next development cycle (#{next_version}.pre)")
run('git', 'push', 'origin', 'main')

puts "\nRelease v#{release_version} complete!"
end
end
Loading