Skip to content

Commit b0b48db

Browse files
authored
Fix release process to commit all spec/dummy lockfiles (#668)
* Improve release process to commit all spec/dummy lockfiles The create_release rake task now commits all three lockfiles that get updated during the release process: - spec/dummy/Gemfile.lock - spec/dummy/package-lock.json - spec/dummy/yarn.lock Previously only Gemfile.lock was committed, leaving uncommitted changes after releases. Also added comprehensive release documentation in docs/releasing.md with: - Prerequisites and setup instructions - Step-by-step release process - Troubleshooting common issues - Manual release steps if needed Updated the rake task description to clearly list all steps.
1 parent cf8f530 commit b0b48db

3 files changed

Lines changed: 224 additions & 11 deletions

File tree

docs/releasing.md

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Releasing Shakapacker
2+
3+
This guide is for Shakapacker maintainers who need to publish a new release.
4+
5+
## Prerequisites
6+
7+
1. **Install required tools:**
8+
9+
```bash
10+
bundle install # Installs gem-release
11+
yarn global add release-it # Installs release-it for npm publishing
12+
```
13+
14+
2. **Ensure you have publishing access:**
15+
16+
- npm: You must be a collaborator on the [shakapacker npm package](https://www.npmjs.com/package/shakapacker)
17+
- RubyGems: You must be an owner of the [shakapacker gem](https://rubygems.org/gems/shakapacker)
18+
19+
3. **Enable 2FA on both platforms:**
20+
- npm: 2FA is required for publishing
21+
- RubyGems: 2FA is required for publishing
22+
23+
## Release Process
24+
25+
### 1. Prepare the Release
26+
27+
Before running the release task:
28+
29+
1. Ensure all desired changes are merged to `main` branch
30+
2. Update `CHANGELOG.md` with the new version and release notes
31+
3. Commit the CHANGELOG changes
32+
4. Ensure your working directory is clean (`git status` shows no uncommitted changes)
33+
34+
### 2. Run the Release Task
35+
36+
The automated release task handles the entire release process:
37+
38+
```bash
39+
# For a specific version (e.g., 9.1.0)
40+
rake create_release[9.1.0]
41+
42+
# For a beta release (note: use period, not dash)
43+
rake create_release[9.2.0.beta.1] # Creates npm package 9.2.0-beta.1
44+
45+
# For a patch version bump (auto-increments)
46+
rake create_release
47+
48+
# Dry run to test without publishing
49+
rake create_release[9.1.0,true]
50+
```
51+
52+
### 3. What the Release Task Does
53+
54+
The `create_release` task automatically:
55+
56+
1. **Pulls latest changes** from the repository
57+
2. **Bumps version numbers** in:
58+
- `lib/shakapacker/version.rb` (Ruby gem version)
59+
- `package.json` (npm package version - converted from Ruby format)
60+
3. **Publishes to npm:**
61+
- Prompts for npm OTP (2FA code)
62+
- Creates git tag
63+
- Pushes to GitHub
64+
4. **Publishes to RubyGems:**
65+
- Prompts for RubyGems OTP (2FA code)
66+
5. **Updates spec/dummy lockfiles:**
67+
- Runs `bundle install` to update `Gemfile.lock`
68+
- Runs `npm install` to update `package-lock.json` (yarn.lock may also be updated for multi-package-manager compatibility testing)
69+
6. **Commits and pushes lockfile changes** automatically
70+
71+
### 4. Version Format
72+
73+
**Important:** Use Ruby gem version format (no dashes):
74+
75+
- ✅ Correct: `9.1.0`, `9.2.0.beta.1`, `9.0.0.rc.2`
76+
- ❌ Wrong: `9.1.0-beta.1`, `9.0.0-rc.2`
77+
78+
The task automatically converts Ruby gem format to npm semver format:
79+
80+
- Ruby: `9.2.0.beta.1` → npm: `9.2.0-beta.1`
81+
- Ruby: `9.0.0.rc.2` → npm: `9.0.0-rc.2`
82+
83+
**Examples:**
84+
85+
```bash
86+
# Regular release
87+
rake create_release[9.1.0] # Gem: 9.1.0, npm: 9.1.0
88+
89+
# Beta release
90+
rake create_release[9.2.0.beta.1] # Gem: 9.2.0.beta.1, npm: 9.2.0-beta.1
91+
92+
# Release candidate
93+
rake create_release[10.0.0.rc.1] # Gem: 10.0.0.rc.1, npm: 10.0.0-rc.1
94+
```
95+
96+
### 5. During the Release
97+
98+
1. When prompted for **npm OTP**, enter your 2FA code from your authenticator app
99+
2. Accept defaults for release-it options
100+
3. When prompted for **RubyGems OTP**, enter your 2FA code
101+
4. The script will automatically commit and push lockfile updates
102+
103+
### 6. After Release
104+
105+
1. Verify the release on:
106+
107+
- [npm](https://www.npmjs.com/package/shakapacker)
108+
- [RubyGems](https://rubygems.org/gems/shakapacker)
109+
- [GitHub releases](https://github.com/shakacode/shakapacker/releases)
110+
111+
2. Check that the lockfile commit was pushed:
112+
113+
```bash
114+
git log --oneline -5
115+
# Should see "Update spec/dummy lockfiles after release"
116+
```
117+
118+
3. Announce the release (if appropriate):
119+
- Post in relevant Slack/Discord channels
120+
- Tweet about major releases
121+
- Update documentation if needed
122+
123+
## Troubleshooting
124+
125+
### Uncommitted Changes After Release
126+
127+
If you see uncommitted changes to lockfiles after a release, this means:
128+
129+
1. The release was successful but the lockfile commit step may have failed
130+
2. **Solution:** Manually commit these files:
131+
```bash
132+
git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
133+
git commit -m 'Update spec/dummy lockfiles after release'
134+
git push
135+
```
136+
137+
### Failed npm or RubyGems Publish
138+
139+
If publishing fails partway through:
140+
141+
1. Check which step failed (npm or RubyGems)
142+
2. If npm failed: Fix the issue and manually run `npm publish`
143+
3. If RubyGems failed: Fix the issue and manually run `gem release`
144+
4. Then manually update and commit spec/dummy lockfiles
145+
146+
### Wrong Version Format
147+
148+
If you accidentally use npm format (with dashes):
149+
150+
1. The gem will be created with an invalid version
151+
2. **Solution:** Don't push the changes, reset your branch:
152+
```bash
153+
git reset --hard HEAD
154+
```
155+
3. Re-run with correct Ruby gem format
156+
157+
## Manual Release Steps
158+
159+
If you need to release manually (not recommended):
160+
161+
1. **Bump version:**
162+
163+
```bash
164+
gem bump --version 9.1.0
165+
bundle install
166+
```
167+
168+
2. **Publish to npm:**
169+
170+
```bash
171+
release-it 9.1.0 --npm.publish
172+
```
173+
174+
3. **Publish to RubyGems:**
175+
176+
```bash
177+
gem release
178+
```
179+
180+
4. **Update lockfiles:**
181+
```bash
182+
cd spec/dummy
183+
bundle install
184+
npm install
185+
cd ../..
186+
git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
187+
git commit -m 'Update spec/dummy lockfiles after release'
188+
git push
189+
```
190+
191+
## Questions?
192+
193+
If you encounter issues not covered here, please:
194+
195+
1. Check the [CONTRIBUTING.md](../CONTRIBUTING.md) guide
196+
2. Ask in the maintainers channel
197+
3. Update this documentation for future releases

rakelib/release.rake

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,16 @@ which are installed via `bundle install` and `yarn global add release-it`
2121
automatically perform a patch version bump.
2222
2nd argument: Perform a dry run by passing 'true' as a second argument.
2323
24+
The task will:
25+
1. Pull latest changes and bump versions
26+
2. Publish to npm (requires OTP)
27+
3. Publish to RubyGems (requires OTP)
28+
4. Update spec/dummy lockfiles (runs bundle install and npm install)
29+
5. Commit and push the lockfile updates
30+
2431
Note, accept defaults for npmjs options. Script will pause to get 2FA tokens.
2532
26-
Example: `rake release[2.1.0,false]`")
33+
Example: `rake create_release[2.1.0,false]`")
2734
task :create_release, %i[gem_version dry_run] do |_t, args|
2835
# Check if there are uncommitted changes
2936
Shakapacker::Utils::Misc.uncommitted_changes?(RaisingMessageHandler.new)
@@ -63,21 +70,31 @@ task :create_release, %i[gem_version dry_run] do |_t, args|
6370

6471
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "gem release") unless is_dry_run
6572

66-
# Update spec/dummy Gemfile.lock to use the new version
73+
# Update spec/dummy lockfiles to use the new version
6774
spec_dummy_dir = File.join(gem_root, "spec", "dummy")
6875
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
6976
puts "Updating spec/dummy dependencies"
7077
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
7178
Shakapacker::Utils::Misc.sh_in_dir(spec_dummy_dir, "bundle install") unless is_dry_run
72-
# Note: spec/dummy uses npm (not yarn) as defined in its packageManager field
79+
# Note: spec/dummy uses npm (matching CI configuration)
7380
Shakapacker::Utils::Misc.sh_in_dir(spec_dummy_dir, "npm install") unless is_dry_run
7481

75-
# Check if there are changes to spec/dummy/Gemfile.lock
76-
changes_output = `git status --porcelain spec/dummy/Gemfile.lock 2>&1`
77-
if !changes_output.strip.empty? && !is_dry_run
78-
puts "Committing and pushing spec/dummy/Gemfile.lock changes"
79-
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "git add spec/dummy/Gemfile.lock")
80-
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "git commit -m 'Update spec/dummy Gemfile.lock after release'")
82+
# Check if there are changes to spec/dummy lockfiles and commit them
83+
# Note: We check both npm and yarn lockfiles since the project supports multiple package managers for testing
84+
require "shellwords"
85+
lockfiles = ["spec/dummy/Gemfile.lock", "spec/dummy/package-lock.json", "spec/dummy/yarn.lock"]
86+
existing_lockfiles = lockfiles.select { |f| File.exist?(File.join(gem_root, f)) }
87+
changed_lockfiles = existing_lockfiles.select do |lockfile|
88+
changes_output = `git -C #{Shellwords.escape(gem_root)} status --porcelain -- #{Shellwords.escape(lockfile)}`
89+
!changes_output.strip.empty?
90+
end
91+
92+
if !changed_lockfiles.empty? && !is_dry_run
93+
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
94+
puts "Committing and pushing spec/dummy lockfile changes: #{changed_lockfiles.join(', ')}"
95+
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
96+
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "git add -- #{changed_lockfiles.join(' ')}")
97+
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "git commit -m 'Update spec/dummy lockfiles after release'")
8198
Shakapacker::Utils::Misc.sh_in_dir(gem_root, "git push")
8299
end
83100
end

spec/dummy/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,5 @@
4747
"webpack-dev-server": "^5.2.2",
4848
"@rspack/dev-server": "^1.1.4",
4949
"@rspack/plugin-react-refresh": "^1.5.1"
50-
},
51-
"packageManager": "yarn@1.22.22"
50+
}
5251
}

0 commit comments

Comments
 (0)