diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 385d992..10f2216 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 b41ea54..cdbcfc7 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 4113b12..f4b9bb4 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: . + - 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, '-') }} files: '*.tgz' + body_path: ${{ github.workspace }}/${{ steps.changelog.outputs.outfile }} npm: name: npm 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..f083565 --- /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' }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Release version ${{ steps.release.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 c02e271..a8c3d95 100644 --- a/README.md +++ b/README.md @@ -19,16 +19,19 @@ Bootstrap a new TypeScript module in five minutes or less. - [Prettier] code. - Futuristic debuggable unit testing with [AVA]. - Code coverage reporting with [Istanbul] and [c8]. -- Continuous testing and package 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]. +- Start coding instantly with [GitHub Codespaces]. [AVA]: https://github.com/avajs/ava [ECMAScript module]: https://nodejs.org/api/esm.html [ESLint]: https://eslint.org/ [EditorConfig]: https://editorconfig.org/ [GitHub Actions]: https://github.com/features/actions +[GitHub Codespaces]: https://github.com/features/codespaces [Istanbul]: https://istanbul.js.org/ [JavaScript Standard Style]: https://standardjs.com/ [Keep a CHANGELOG]: https://keepachangelog.com/ @@ -39,6 +42,7 @@ Bootstrap a new TypeScript module in five minutes or less. [c8]: https://github.com/bcoe/c8 [landlubber]: https://github.com/razor-x/landlubber [npm]: https://www.npmjs.com/ +[semantic-release]: https://semantic-release.gitbook.io/semantic-release/ [yargs]: https://yargs.js.org/ ### Bootstrapping a new project @@ -198,7 +202,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 42d88cc..0b228ce 100755 --- a/makenew.sh +++ b/makenew.sh @@ -57,7 +57,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,103d' + sed_delete README.md '10,107d' sed_insert README.md '10i' 'TODO' find_replace "s/^ \"version\": \".*\"/ \"version\": \"0.0.0\"/g"