From 4922bdfec5db3bbd8ddd34b29587c87aade4edae Mon Sep 17 00:00:00 2001 From: Andrey Novikov Date: Thu, 4 Jan 2024 18:14:31 +0900 Subject: [PATCH] Set up automatic gem releasing on tag creation [ci skip] --- .github/workflows/release.yml | 82 +++++++++++++++++++++++++++++++++++ README.md | 33 ++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..bf36bdb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,82 @@ +name: Release gem to RubyGems + +on: + push: + tags: + - v* + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + packages: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch current tag as annotated. See https://github.com/actions/checkout/issues/290 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.2 + - name: "Extract data from tag: version, message, body" + id: tag + run: | + git fetch --tags --force # Really fetch annotated tag. See https://github.com/actions/checkout/issues/290#issuecomment-680260080 + echo ::set-output name=version::${GITHUB_REF#refs/tags/v} + echo ::set-output name=subject::$(git for-each-ref $GITHUB_REF --format='%(contents:subject)') + BODY="$(git for-each-ref $GITHUB_REF --format='%(contents:body)')" + # Extract changelog entries between this and previous version headers + escaped_version=$(echo ${GITHUB_REF#refs/tags/v} | sed -e 's/[]\/$*.^[]/\\&/g') + changelog=$(awk "BEGIN{inrelease=0} /## \[${escaped_version}\]/{inrelease=1;next} /## \[[0-9]+\.[0-9]+\.[0-9]+.*?\]/{inrelease=0;exit} {if (inrelease) print}" CHANGELOG.md) + # Multiline body for release. See https://github.community/t/set-output-truncates-multiline-strings/16852/5 + BODY="${BODY}"$'\n'"${changelog}" + BODY="${BODY//'%'/'%25'}" + BODY="${BODY//$'\n'/'%0A'}" + BODY="${BODY//$'\r'/'%0D'}" + echo "::set-output name=body::$BODY" + # Add pre-release option if tag name has any suffix after vMAJOR.MINOR.PATCH + if [[ ${GITHUB_REF#refs/tags/} =~ ^v[0-9]+\.[0-9]+\.[0-9]+.+ ]]; then + echo ::set-output name=prerelease::true + fi + - name: Build gem + run: gem build + - name: Calculate checksums + run: sha256sum yabeda-gc-${{ steps.tag.outputs.version }}.gem > SHA256SUM + - name: Check version + run: ls -l yabeda-gc-${{ steps.tag.outputs.version }}.gem + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ steps.tag.outputs.subject }} + body: ${{ steps.tag.outputs.body }} + draft: false + prerelease: ${{ steps.tag.outputs.prerelease }} + - name: Upload built gem as release asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: yabeda-gc-${{ steps.tag.outputs.version }}.gem + asset_name: yabeda-gc-${{ steps.tag.outputs.version }}.gem + asset_content_type: application/x-tar + - name: Upload checksums as release asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: SHA256SUM + asset_name: SHA256SUM + asset_content_type: text/plain + - name: Configure RubyGems Credentials + uses: rubygems/configure-rubygems-credentials@main + - name: Publish to RubyGems + run: | + gem push yabeda-gc-${{ steps.tag.outputs.version }}.gem diff --git a/README.md b/README.md index 93d5cd5..98ffb44 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,39 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). +## Releasing + +1. Bump version number in `lib/yabeda/gc/version.rb` + + In case of pre-releases keep in mind [rubygems/rubygems#3086](https://github.com/rubygems/rubygems/issues/3086) and check version with command like `Gem::Version.new(Yabeda::gc::VERSION).to_s` + +2. Fill `CHANGELOG.md` with missing changes, add header with version and date. + +3. Make a commit: + + ```sh + bundle # to update Gemfile.lock + git add lib/yabeda/gc/version.rb CHANGELOG.md Gemfile.lock + version=$(ruby -r ./lib/yabeda/gc/version.rb -e "puts Gem::Version.new(Yabeda::GC::VERSION)") + git commit --message="${version}: " --edit + ``` + +4. Create annotated tag: + + ```sh + git tag v${version} --annotate --message="${version}: " --edit --sign + ``` + +5. Fill version name into subject line and (optionally) some description (list of changes will be taken from changelog and appended automatically) + +6. Push it: + + ```sh + git push --follow-tags + ``` + +7. GitHub Actions will create a new release, build and push gem into RubyGems! You're done! + ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/ianks/yabeda-gc. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ianks/yabeda-gc/blob/master/CODE_OF_CONDUCT.md).