From 5531e7d534ad663be4f0171b4f2a54e8595efd1c Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 30 Sep 2025 16:32:48 -1000 Subject: [PATCH 1/4] Add simplified gem release process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a streamlined release process for the cypress-on-rails gem, removing the npm package release steps that were present in the react_on_rails version. Key changes: - Add lib/tasks/release.rake with gem-only release automation - Add docs/RELEASE.md with comprehensive release documentation - Simplify process by removing release-it and npm publishing steps - Keep essential features: version bumping, git tagging, and gem publishing The release task handles: - Checking for uncommitted changes - Pulling latest changes - Bumping version using gem-release - Publishing to RubyGems with OTP support - Providing post-release instructions for CHANGELOG updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/RELEASE.md | 116 +++++++++++++++++++++++++++++++++++++++++ lib/tasks/release.rake | 49 +++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 docs/RELEASE.md create mode 100644 lib/tasks/release.rake diff --git a/docs/RELEASE.md b/docs/RELEASE.md new file mode 100644 index 0000000..d3c50b1 --- /dev/null +++ b/docs/RELEASE.md @@ -0,0 +1,116 @@ +# Release Process + +This document describes how to release a new version of the `cypress-on-rails` gem. + +## Prerequisites + +1. Install the `gem-release` gem globally: + ```bash + gem install gem-release + ``` + +2. Ensure you have write access to the rubygems.org package + +3. Set up two-factor authentication (2FA) for RubyGems and have your OTP generator ready + +## Release Steps + +### 1. Prepare for Release + +Ensure your working directory is clean: +```bash +git status +``` + +If you have uncommitted changes, commit or stash them first. + +### 2. Pull Latest Changes + +```bash +git pull --rebase +``` + +### 3. Run the Release Task + +To release a specific version: +```bash +rake release[1.19.0] +``` + +To automatically bump the patch version: +```bash +rake release +``` + +To perform a dry run (without actually publishing): +```bash +rake release[1.19.0,true] +``` + +### 4. Enter Your OTP + +When prompted, enter your one-time password (OTP) from your authenticator app for RubyGems. + +If you get an error during gem publishing, you can run `gem release` manually to retry. + +### 5. Update the CHANGELOG + +After successfully publishing the gem, update the CHANGELOG: + +```bash +bundle exec rake update_changelog +git commit -a -m 'Update CHANGELOG.md' +git push +``` + +## Version Numbering + +Follow [Semantic Versioning](https://semver.org/): + +- **Major version** (X.0.0): Breaking changes +- **Minor version** (0.X.0): New features, backwards compatible +- **Patch version** (0.0.X): Bug fixes, backwards compatible + +## What the Release Task Does + +The release task automates the following steps: + +1. Checks for uncommitted changes (will abort if found) +2. Pulls the latest changes from the repository +3. Bumps the version number in `lib/cypress_on_rails/version.rb` +4. Creates a git commit with the version bump +5. Creates a git tag for the new version +6. Pushes the commit and tag to GitHub +7. Builds the gem +8. Publishes the gem to RubyGems + +## Troubleshooting + +### Authentication Error + +If you get an authentication error with RubyGems: +1. Verify your OTP is correct and current +2. Ensure your RubyGems API key is valid +3. Run `gem release` manually to retry + +### Version Already Exists + +If the version already exists on RubyGems: +1. Bump to a higher version number +2. Or fix the version in `lib/cypress_on_rails/version.rb` and try again + +### Uncommitted Changes Error + +If you have uncommitted changes: +1. Review your changes with `git status` +2. Commit them with `git commit -am "Your message"` +3. Or stash them with `git stash` +4. Then retry the release + +## Post-Release + +After releasing: + +1. Announce the release on relevant channels (Slack, forum, etc.) +2. Update any documentation that references version numbers +3. Consider creating a GitHub release with release notes diff --git a/lib/tasks/release.rake b/lib/tasks/release.rake new file mode 100644 index 0000000..de06fb1 --- /dev/null +++ b/lib/tasks/release.rake @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +desc("Releases the gem using the given version. + +IMPORTANT: the gem version must be in valid rubygem format (no dashes). + +This task depends on the gem-release ruby gem which is installed via `bundle install` + +1st argument: The new version in rubygem format (no dashes). Pass no argument to + automatically perform a patch version bump. +2nd argument: Perform a dry run by passing 'true' as a second argument. + +Example: `rake release[1.19.0,false]`") +task :release, %i[gem_version dry_run] do |_t, args| + def sh_in_dir(dir, command) + puts "Running in #{dir}: #{command}" + system("cd #{dir} && #{command}") || raise("Command failed: #{command}") + end + + def gem_root + File.expand_path('..', __dir__) + end + + # Check if there are uncommitted changes + unless `git status --porcelain`.strip.empty? + raise "You have uncommitted changes. Please commit or stash them before releasing." + end + + args_hash = args.to_hash + is_dry_run = args_hash[:dry_run] == 'true' + gem_version = args_hash.fetch(:gem_version, "") + + # See https://github.com/svenfuchs/gem-release + sh_in_dir(gem_root, "git pull --rebase") + sh_in_dir(gem_root, "gem bump --no-commit #{%(--version #{gem_version}) unless gem_version.strip.empty?}") + + # Release the new gem version + puts "Carefully add your OTP for Rubygems. If you get an error, run 'gem release' again." + sh_in_dir(gem_root, "gem release") unless is_dry_run + + msg = <<~MSG + Once you have successfully published, run these commands to update CHANGELOG.md: + + bundle exec rake update_changelog + git commit -a -m 'Update CHANGELOG.md' + git push + MSG + puts msg +end From 0aa687e4bc6b9b1b92fe7338b0c3714a633c0c5b Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 30 Sep 2025 19:43:21 -1000 Subject: [PATCH 2/4] Add beta version format clarification to release docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specify that pre-release versions must use dot notation (e.g., 2.0.0.beta.1) rather than dash notation (e.g., 2.0.0-beta.1) as required by RubyGems. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/RELEASE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index d3c50b1..4a5479e 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -70,6 +70,7 @@ Follow [Semantic Versioning](https://semver.org/): - **Major version** (X.0.0): Breaking changes - **Minor version** (0.X.0): New features, backwards compatible - **Patch version** (0.0.X): Bug fixes, backwards compatible +- **Pre-release versions**: Use dot notation, not dashes (e.g., `2.0.0.beta.1`, not `2.0.0-beta.1`) ## What the Release Task Does From 46992242a3d1bdad70934a6e2bcf2f5ddee7cbff Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 30 Sep 2025 19:46:23 -1000 Subject: [PATCH 3/4] Remove reference to non-existent update_changelog task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The update_changelog task doesn't exist in this repository - it was copied from react_on_rails but never implemented here. Update both the release.rake and RELEASE.md to indicate manual CHANGELOG updates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/RELEASE.md | 4 ++-- lib/tasks/release.rake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 4a5479e..9a928ce 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -55,10 +55,10 @@ If you get an error during gem publishing, you can run `gem release` manually to ### 5. Update the CHANGELOG -After successfully publishing the gem, update the CHANGELOG: +After successfully publishing the gem, manually update the CHANGELOG: ```bash -bundle exec rake update_changelog +# Edit CHANGELOG.md to document the new release git commit -a -m 'Update CHANGELOG.md' git push ``` diff --git a/lib/tasks/release.rake b/lib/tasks/release.rake index de06fb1..5846b39 100644 --- a/lib/tasks/release.rake +++ b/lib/tasks/release.rake @@ -39,9 +39,9 @@ task :release, %i[gem_version dry_run] do |_t, args| sh_in_dir(gem_root, "gem release") unless is_dry_run msg = <<~MSG - Once you have successfully published, run these commands to update CHANGELOG.md: + Once you have successfully published, manually update CHANGELOG.md: - bundle exec rake update_changelog + # Edit CHANGELOG.md to document the new release git commit -a -m 'Update CHANGELOG.md' git push MSG From 26465fcd52c108740c5d09cf927bdb2929587307 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Tue, 30 Sep 2025 19:49:20 -1000 Subject: [PATCH 4/4] Add update_changelog rake task from react_on_rails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copied and adapted the update_changelog task from react_on_rails to automatically update CHANGELOG.md with new version headers and links. Key features: - Automatically detects latest git tag - Inserts new version header with release date under [Unreleased] - Updates version comparison links at bottom of CHANGELOG - Handles version tags with or without 'v' prefix - Provides clear next steps for manual edits Also updated release.rake and RELEASE.md to reference the new task. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/RELEASE.md | 10 ++++-- lib/tasks/release.rake | 5 +-- lib/tasks/update_changelog.rake | 63 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 lib/tasks/update_changelog.rake diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 9a928ce..cec6aed 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -55,10 +55,16 @@ If you get an error during gem publishing, you can run `gem release` manually to ### 5. Update the CHANGELOG -After successfully publishing the gem, manually update the CHANGELOG: +After successfully publishing the gem, update the CHANGELOG: ```bash -# Edit CHANGELOG.md to document the new release +bundle exec rake update_changelog +# This will: +# - Add a new version header with the release date +# - Add version comparison links +# - Prompt you to move content from [Unreleased] to the new version + +# Edit CHANGELOG.md to move unreleased changes to the new version section git commit -a -m 'Update CHANGELOG.md' git push ``` diff --git a/lib/tasks/release.rake b/lib/tasks/release.rake index 5846b39..486a615 100644 --- a/lib/tasks/release.rake +++ b/lib/tasks/release.rake @@ -39,9 +39,10 @@ task :release, %i[gem_version dry_run] do |_t, args| sh_in_dir(gem_root, "gem release") unless is_dry_run msg = <<~MSG - Once you have successfully published, manually update CHANGELOG.md: + Once you have successfully published, update CHANGELOG.md: - # Edit CHANGELOG.md to document the new release + bundle exec rake update_changelog + # Edit CHANGELOG.md to move unreleased changes to the new version section git commit -a -m 'Update CHANGELOG.md' git push MSG diff --git a/lib/tasks/update_changelog.rake b/lib/tasks/update_changelog.rake new file mode 100644 index 0000000..9a44ad0 --- /dev/null +++ b/lib/tasks/update_changelog.rake @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "English" + +desc "Updates CHANGELOG.md inserting headers for the new version. + +Argument: Git tag. Defaults to the latest tag." + +task :update_changelog, %i[tag] do |_, args| + tag = args[:tag] || `git describe --tags --abbrev=0`.strip + + # Remove 'v' prefix if present (e.g., v1.18.0 -> 1.18.0) + version = tag.start_with?('v') ? tag[1..-1] : tag + anchor = "[#{version}]" + + changelog = File.read("CHANGELOG.md") + + if changelog.include?(anchor) + puts "Tag #{version} is already documented in CHANGELOG.md, update manually if needed" + next + end + + tag_date_output = `git show -s --format=%cs #{tag} 2>&1` + if $CHILD_STATUS.success? + tag_date = tag_date_output.split("\n").last.strip + else + abort("Failed to find tag #{tag}") + end + + # After "## [Unreleased]", insert new version header + unreleased_section = "## [Unreleased]" + new_version_header = "\n\n## #{anchor} - #{tag_date}" + + if changelog.include?(unreleased_section) + changelog.sub!(unreleased_section, "#{unreleased_section}#{new_version_header}") + else + abort("Could not find '## [Unreleased]' section in CHANGELOG.md") + end + + # Find and update version comparison links at the bottom + # Pattern: [1.18.0]: https://github.com/shakacode/cypress-playwright-on-rails/compare/v1.17.0...v1.18.0 + compare_link_prefix = "https://github.com/shakacode/cypress-playwright-on-rails/compare" + + # Find the last version link to determine the previous version + last_version_match = changelog.match(/\[(\d+\.\d+\.\d+(?:\.\w+)?)\]:.*?compare\/v(\d+\.\d+\.\d+(?:\.\w+)?)\.\.\.v(\d+\.\d+\.\d+(?:\.\w+)?)/) + + if last_version_match + last_version = last_version_match[1] + # Add new version link at the top of the version list + new_link = "#{anchor}: #{compare_link_prefix}/v#{last_version}...v#{version}" + # Insert after the "" comment + changelog.sub!("", "\n#{new_link}") + else + puts "Warning: Could not find version comparison links. You may need to add the link manually." + end + + File.write("CHANGELOG.md", changelog) + puts "Updated CHANGELOG.md with an entry for #{version}" + puts "\nNext steps:" + puts "1. Edit CHANGELOG.md to add release notes under the [#{version}] section" + puts "2. Move content from [Unreleased] to [#{version}] if applicable" + puts "3. Review and commit the changes" +end