diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000..e5c84b75eda69 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + release: + types: [published] + +jobs: + release: + permissions: + contents: write + id-token: write + + environment: release + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby + - uses: actions/setup-node@v4 + with: + node-version: lts/* + registry-url: 'https://registry.npmjs.org' + - name: Configure trusted publishing credentials + uses: rubygems/configure-rubygems-credentials@v1.0.0 + - name: Bundle install + run: bundle install + working-directory: tools/releaser + - name: Run release rake task + run: bundle exec rake push + shell: bash + working-directory: tools/releaser + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Wait for release to propagate + run: gem exec rubygems-await pkg/*.gem + shell: bash diff --git a/RELEASING_RAILS.md b/RELEASING_RAILS.md index 14c968bed0541..eeb0c2ba29fa0 100644 --- a/RELEASING_RAILS.md +++ b/RELEASING_RAILS.md @@ -24,7 +24,7 @@ Obviously Rails cannot be released when it depends on unreleased code. Contact the authors of those particular gems and work out a release date that suits them. -### Announce your plans to the rest of the team on Campfire +### Announce your plans to the rest of the team on Basecamp Let them know of your plans to release. @@ -56,58 +56,38 @@ Include an RC number if appropriate, e.g. `6.0.0.rc1`. ### Build and test the gem. -Run `rake verify` to generate the gems and install them locally. `verify` also -generates a Rails app with a migration and boots it to smoke test with in your -browser. +Run `rake install` to generate the gems and install them locally. You can now +use the version installed locally to generate a new app and check if everything +is working as expected. This will stop you from looking silly when you push an RC to rubygems.org and then realize it is broken. -### Check credentials for RubyGems, npm, and GitHub - -For npm run `npm whoami` to check that you are logged in (`npm login` if not). - -For RubyGems run `gem login`. If there's no output you are logged in. +### Check credentials for GitHub For GitHub run `gh auth status` to check that you are logged in (run `gh login` if not). -npm and RubyGems require MFA. The release task will attempt to use a yubikey if -available, which as we have release several packages at once is strongly -recommended. Check that `ykman oath accounts list` has an entry for both -`npmjs.com` and `rubygems.org`, if not refer to -https://tenderlovemaking.com/2021/10/26/publishing-gems-with-your-yubikey.html -for setup instructions. - -### Release to RubyGems and npm. - -IMPORTANT: Several gems have JavaScript components that are released as npm -packages, so you must have Node.js installed, have an npm account (npmjs.com), -and be a package owner for `@rails/actioncable`, `@rails/actiontext`, and -`@rails/activestorage`. You can check this by making sure your -npm user (`npm whoami`) is listed as an owner (`npm owner ls `) of each -package. Do not release until you're set up with npm! - The release task will sign the release tag. If you haven't got commit signing set up, use https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work as a guide. You can generate keys with the GPG suite from here: https://gpgtools.org. -Run `rake changelog:header` to put a header with the new version in every -CHANGELOG. Don't commit this, the release task handles it. +Run `rake prep_release` to prepare the release. This will populate the gemspecs and +npm package.json with the current RAILS_VERSION, add the header to the CHANGELOGs, +build the gems, and check if bundler can resolve the dependencies. -Run `rake release`. This will populate the gemspecs and npm package.json with -the current RAILS_VERSION, commit the changes, tag it, and push the gems to -rubygems.org. +You can now inspect the results in the diff and see if you are happy with the +changes. -### Make GitHub Releases from pushed tags +To release, Run `rake release`. This will commit the changes, tag it, and create a GitHub +release with the proper release notes in draft mode. -We use GitHub Releases to publish the combined release summary for all gems. We -can use a rake task and [GitHub cli](https://cli.github.com/) to do this -(releases can also be created or edited on the web). +Open the corresponding GitHub release draft and check that the release notes +are correct. If everything is fine, publish the release. -``` -bundle exec rake changelog:release_summary > ../6-1-7-release-summary.md -gh release create v6.1.7 -R rails/rails -F ../6-1-7-release-summary.md -``` +### Publish the gems + +To publish the gems approve the [Release workflow in GitHub Actions](https://github.com/rails/rails/actions/workflows/release.yml), +that was created after the release was published. ### Send Rails release announcements @@ -117,7 +97,6 @@ lists where you should announce: * [rubyonrails-core](https://discuss.rubyonrails.org/c/rubyonrails-core) * [rubyonrails-talk](https://discuss.rubyonrails.org/c/rubyonrails-talk) -* ruby-talk@ruby-lang.org Use Markdown format for your announcement. Remember to ask people to report issues with the release candidate to the rails-core mailing list. diff --git a/tools/releaser/lib/releaser.rb b/tools/releaser/lib/releaser.rb index 78aee04df2c0d..2439418a30982 100644 --- a/tools/releaser/lib/releaser.rb +++ b/tools/releaser/lib/releaser.rb @@ -157,7 +157,7 @@ def define end desc "Release all gems and create a tag" - task release: %w(check_gh_client prep_release commit tag create_release push) + task release: %w(check_gh_client prep_release commit tag create_release) desc "Push the gem to rubygems.org and the npm package to npmjs.com" task push: FRAMEWORKS.map { |f| "#{f}:push" } + ["rails:push"] @@ -288,7 +288,7 @@ def inexistent_tag? def npm_otp " --otp " + ykman("npmjs.com") rescue - "" + " --provenance --access public" end def gem_otp