diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 0fffd2a..d0bd0b7 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -35,7 +35,7 @@ jobs: uses: stefanzweifel/git-auto-commit-action@v5 if: always() with: - commit_message: Run format + commit_message: 'ci: Format code' commit_user_name: ${{ secrets.GIT_USER_NAME }} commit_user_email: ${{ secrets.GIT_USER_EMAIL }} commit_author: ${{ secrets.GIT_USER_NAME }} <${{ secrets.GIT_USER_EMAIL }}> diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index e2fd5ab..b38c9d0 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -36,7 +36,7 @@ jobs: - name: Commit uses: stefanzweifel/git-auto-commit-action@v5 with: - commit_message: Generate code + commit_message: 'ci: Generate code' commit_user_name: ${{ secrets.GIT_USER_NAME }} commit_user_email: ${{ secrets.GIT_USER_EMAIL }} commit_author: ${{ secrets.GIT_USER_NAME }} <${{ secrets.GIT_USER_EMAIL }}> diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9acb18a..75fb59e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,11 +20,21 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Download artifact uses: actions/download-artifact@v4 with: name: ${{ needs.build.outputs.artifact_name }} path: pkg/ + - name: Generate release notes + id: changelog + run: | + mkdir tmp + outfile=tmp/changelog.txt + echo "outfile=${outfile}" >> $GITHUB_OUTPUT + npx standard-changelog@^2.0.0 --release-count 2 --infile $outfile.tmp --outfile $outfile.tmp + sed '1,3d' $outfile.tmp > $outfile - name: Create GitHub release uses: softprops/action-gh-release@v2 with: @@ -32,6 +42,7 @@ jobs: fail_on_unmatched_files: true prerelease: ${{ contains(github.ref_name, 'pre') }} files: pkg/* + body_path: ${{ github.workspace }}/${{ steps.changelog.outputs.outfile }} rubygems: name: RubyGems.org uses: ./.github/workflows/_publish.yml diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml new file mode 100644 index 0000000..20a1f4f --- /dev/null +++ b/.github/workflows/semantic-release.yml @@ -0,0 +1,49 @@ +--- +name: Semantic Release + +run-name: Semantic Release from ${{ github.ref_name }} + +on: + push: + branches: + - '**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + semantic: + name: Determine version + runs-on: ubuntu-latest + timeout-minutes: 30 + outputs: + new_release_published: ${{ steps.release.outputs.new_release_published }} + new_release_version: ${{ steps.release.outputs.new_release_version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Semantic release + id: release + uses: cycjimmy/semantic-release-action@v4 + with: + dry_run: true + release: + name: Release version + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: semantic + if: needs.semantic.outputs.new_release_published == 'true' && needs.semantic.outputs.new_release_version != '1.0.0' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Release version ${{ needs.semantic.outputs.new_release_version }} on ${{ github.ref_name }} + run: gh workflow run version.yml --raw-field version=$VERSION --ref $BRANCH + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + VERSION: ${{ needs.semantic.outputs.new_release_version }} + BRANCH: ${{ github.ref_name }} diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..bd9c6e5 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,11 @@ +{ + "branches": [ + "+([0-9])?(.{+([0-9]),x}).x", + "main", + "next", + "next-major", + { "name": "beta", "prerelease": true }, + { "name": "alpha", "prerelease": true } + ], + "plugins": ["@semantic-release/commit-analyzer"] +} diff --git a/README.md b/README.md index ca639bc..366d335 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Bootstrap a new Ruby gem in five minutes or less. - [Standard] Ruby style guide, linter, and formatter. - Productive and fun testing with [RSpec]. - Code coverage reporting with [SimpleCov]. -- Continuous testing and gem publishing with [GitHub Actions]. +- Fully automated version management and package publishing with [semantic-release]. +- Continuous checks and tests with [GitHub Actions]. - [Keep a CHANGELOG]. - Consistent coding with [EditorConfig]. - Badges from [Shields.io]. @@ -32,6 +33,7 @@ Bootstrap a new Ruby gem in five minutes or less. [rspec]: https://rspec.info/ [ruby]: https://www.ruby-lang.org/ [rubygems.org]: https://rubygems.org/ +[semantic-release]: https://semantic-release.gitbook.io/semantic-release/ [shields.io]: https://shields.io/ [simplecov]: https://github.com/simplecov-ruby/simplecov [standard]: https://github.com/testdouble/standard @@ -192,7 +194,7 @@ These must be set manually. ### Secrets for Optional GitHub Actions -The version and format GitHub actions +The version, format, generate, and semantic-release GitHub actions require a user with write access to the repository. Set these additional secrets to enable the action: diff --git a/makenew.sh b/makenew.sh index caa693a..6dc28e0 100755 --- a/makenew.sh +++ b/makenew.sh @@ -58,7 +58,7 @@ makenew () { read -p '> GitHub user or organization name (my-user): ' mk_user read -p '> GitHub repository name (my-repo): ' mk_repo - sed_delete README.md '10,98d' + sed_delete README.md '10,100d' sed_insert README.md '10i' 'TODO' find_replace "s/^ \"VERSION\" = \".*\"/ \"VERSION\" = \"0.0.0\"/g"