diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..439791b --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,54 @@ +name: Create GitHub Release + +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + create-github-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine current version in pubspec.yaml + id: pubspec-version-number + run: | + PUBSPEC_VERSION=$(yq ".version" pubspec.yaml) + echo "pubspec-version=$PUBSPEC_VERSION" >> $GITHUB_OUTPUT + + - name: Check if version tag already exists + id: tag-check + run: | + TAG=v${{ steps.pubspec-version-number.outputs.pubspec-version }} + if git show-ref --tags --verify --quiet "refs/tags/${TAG}"; then + echo "Version tag $TAG already exists, not creating a new release." + else + echo "new-tag=$TAG" >> $GITHUB_OUTPUT + fi + + - name: Generate release notes + uses: orhun/git-cliff-action@v3 + if: ${{ steps.tag-check.outputs.new-tag != '' }} + with: + config: cliff.toml + args: --verbose --unreleased --strip header --tag ${{ steps.pubspec-version-number.outputs.pubspec-version }} + env: + OUTPUT: CHANGES.md + GITHUB_REPO: ${{ github.repository }} + + - name: Create new GitHub release if tag does not exist yet + uses: ncipollo/release-action@v1 + if: ${{ steps.tag-check.outputs.new-tag != '' }} + with: + tag: ${{ steps.tag-check.outputs.new-tag }} + bodyFile: CHANGES.md + name: Version ${{ steps.pubspec-version-number.outputs.pubspec-version }} + token: ${{ secrets.RELEASE_TOKEN }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000..33d1886 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,69 @@ +name: Prepare next release + +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + prepare-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate a changelog + id: git-cliff + uses: orhun/git-cliff-action@v3 + with: + config: cliff.toml + args: --verbose --bump + env: + OUTPUT: CHANGELOG.md + GITHUB_REPO: ${{ github.repository }} + + - name: Determine changes + uses: orhun/git-cliff-action@v3 + id: git-cliff-changes + with: + config: cliff.toml + args: --verbose --bump --unreleased --strip header + env: + OUTPUT: CHANGES.md + GITHUB_REPO: ${{ github.repository }} + + - name: Format and set new version number + id: version-number + run: | + NEW_VERSION=$(echo ${{ steps.git-cliff.outputs.version }}| cut -d'v' -f 2) + echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT + + - name: Write new version to pubspec.yaml + run: | + NEW_VERSION=${{ steps.version-number.outputs.version }} + sed -i "/^\(^version: \).*/s//\1$NEW_VERSION/" pubspec.yaml + + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.RELEASE_TOKEN }} + commit-message: "chore(release): prepare release ${{ steps.version-number.outputs.version }}" + + signoff: true + branch: next-release + delete-branch: true + title: 'chore(release): prepare release ${{ steps.version-number.outputs.version }}' + body-path: CHANGES.md + labels: | + release + draft: true + add-paths: | + pubspec.yaml + CHANGELOG.md diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..2bd6e16 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,13 @@ +name: Publish to pub.dev + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + +# Publish using the reusable workflow from dart-lang. +jobs: + publish: + permissions: + id-token: write # Required for authentication using OIDC + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index 6e30617..0000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: release-please - -on: - push: - branches: - - main - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: googleapis/release-please-action@v4 - with: - release-type: dart diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..556a8cc --- /dev/null +++ b/cliff.toml @@ -0,0 +1,95 @@ +# git-cliff ~ configuration file +# +# Based on the MIT-licensed example hosted under +# https://github.com/orhun/git-cliff/blob/main/examples/keepachangelog.toml + +[changelog] +# changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{% if version -%} + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else -%} + ## [Unreleased] +{% endif -%} +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]($REPO/commit/{{ commit.id }}))\ + {% endfor %} +{% endfor %}\n +""" + +# template for the changelog footer +footer = """ +{% for release in releases -%} + {% if release.version -%} + {% if release.previous.version -%} + [{{ release.version | trim_start_matches(pat="v") }}]: \ + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}\ + /compare/{{ release.previous.version }}..{{ release.version }} + {% else -%} + [{{ release.version | trim_start_matches(pat="v") }}]: \ + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}\ + /releases/tag/{{ release.version }} + {% endif -%} + {% else -%} + [Unreleased]: https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}\ + /compare/{{ release.previous.version }}..HEAD + {% endif -%} +{% endfor %} + +""" +# remove the leading and trailing whitespace from the templates +trim = true +# postprocessors +postprocessors = [ + { pattern = '\$REPO', replace = "https://github.com/eclipse-thingweb/dart_wot" }, +] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^doc", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactor" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore\\(release\\): prepare release", skip = true }, + { message = "^chore|^ci", group = "Miscellaneous Tasks" }, + { body = ".*security", group = "Security" }, +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = true +# regex for matching git tags +tag_pattern = "v[0-9].*" +# regex for skipping tags +skip_tags = "beta|alpha" +# regex for ignoring tags +ignore_tags = "" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" + +[bump] +features_always_bump_minor = false +breaking_always_bump_major = false