From ae4ff5be0029c506e79d4b91243150069c3373ec Mon Sep 17 00:00:00 2001 From: Mattia Panzeri <1754457+panz3r@users.noreply.github.com> Date: Tue, 29 Sep 2026 23:19:58 +0200 Subject: [PATCH] ci: release weekly from git history with git-cliff instead of release-please --- .github/workflows/release.yml | 157 ++++++++++++++++------------------ .release-please-manifest.json | 1 - CHANGELOG.md | 2 + README.md | 4 + cliff.toml | 36 ++++++++ release-please-config.json | 10 --- 6 files changed, 114 insertions(+), 96 deletions(-) delete mode 100644 .release-please-manifest.json create mode 100644 cliff.toml delete mode 100644 release-please-config.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c5a9de4..9ecc0d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,114 +1,101 @@ name: Release on: - push: - branches: - - main schedule: - cron: "0 17 * * 2" # Weekly on Tuesday evenings workflow_dispatch: + inputs: + dry-run: + description: Compute the next version and release notes without publishing + type: boolean + default: false -jobs: - release-please: - name: Run Release Please - - runs-on: ubuntu-latest - - permissions: - contents: write - pull-requests: write - - outputs: - releases_created: ${{ steps.release.outputs.releases_created }} - - steps: - - name: Run release-please command - id: release - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 - - merge-release-pr: - name: Merge Release PR - - runs-on: ubuntu-latest - - needs: [release-please] - - if: github.event_name == 'schedule' && needs.release-please.outputs.releases_created != 'true' - - permissions: - actions: write - contents: write - pull-requests: write - - env: - GH_TOKEN: ${{ github.token }} - GH_REPO: ${{ github.repository }} - - steps: - - name: Find pending release PR - id: pr - run: | - gh pr list --state open --label "autorelease: pending" --json number,headRefName,headRefOid \ - --jq '.[0] // empty | "number=\(.number)\nbranch=\(.headRefName)\nsha=\(.headRefOid)"' >> "$GITHUB_OUTPUT" - - # Pushes made with GITHUB_TOKEN don't trigger CI, so dispatch it to get the required checks - - name: Run Build & Test on release PR - if: steps.pr.outputs.number - env: - PR_NUMBER: ${{ steps.pr.outputs.number }} - PR_BRANCH: ${{ steps.pr.outputs.branch }} - run: | - gh workflow run build-test.yml --ref "$PR_BRANCH" - sleep 30 - gh pr checks "$PR_NUMBER" --required --watch --fail-fast --interval 30 +permissions: + contents: read - - name: Merge release PR - if: steps.pr.outputs.number - env: - PR_NUMBER: ${{ steps.pr.outputs.number }} - PR_SHA: ${{ steps.pr.outputs.sha }} - run: gh pr merge "$PR_NUMBER" --squash --match-head-commit "$PR_SHA" +concurrency: + group: release - # The merge push is made with GITHUB_TOKEN and won't start this workflow on its own - - name: Trigger release - if: steps.pr.outputs.number - run: gh workflow run release.yml --ref main - - build-and-publish: - name: Build & Publish +jobs: + release: + name: Release runs-on: ubuntu-latest - needs: [release-please] - - if: needs.release-please.outputs.releases_created != 'false' - - concurrency: publish-group # optional: ensure only one action runs at a time - permissions: - contents: read - id-token: write + contents: write # create the tag and GitHub release + id-token: write # npm trusted publishing steps: - name: Checkout repository uses: actions/checkout@v7 + with: + fetch-depth: 0 - - name: Setup pnpm - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 + - name: Generate release notes + id: notes + uses: orhun/git-cliff-action@a9a95522b26fe6403f7bb24031f21fb573d0f5ff # v4.9.1 with: - install: false + args: --unreleased --bump --strip all --output ${{ runner.temp }}/RELEASE_NOTES.md - - name: Setup NodeJS - uses: actions/setup-node@v7 + # git-cliff reports the latest tag as the next version when nothing is releasable + - name: Check for releasable changes + id: check + env: + NOTES: ${{ runner.temp }}/RELEASE_NOTES.md + VERSION: ${{ steps.notes.outputs.version }} + run: | + if ! grep -q '[^[:space:]]' "$NOTES" || git rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then + echo "No releasable changes since the last release" + echo "release=false" >> "$GITHUB_OUTPUT" + else + { echo "## $VERSION"; echo; cat "$NOTES"; } >> "$GITHUB_STEP_SUMMARY" + echo "release=true" >> "$GITHUB_OUTPUT" + fi + + - name: Setup pnpm & Node.js + if: steps.check.outputs.release == 'true' + uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0 with: - node-version: latest - registry-url: 'https://registry.npmjs.org' + runtime: node@latest + install: false - name: Install dependencies + if: steps.check.outputs.release == 'true' run: pnpm i --frozen-lockfile - name: Build CLI + if: steps.check.outputs.release == 'true' run: pnpm build + - name: Set package version + if: steps.check.outputs.release == 'true' + env: + VERSION: ${{ steps.notes.outputs.version }} + run: pnpm version "${VERSION#v}" --no-git-tag-version --allow-same-version + + # pnpm publishes via npm trusted publishing (OIDC) itself; the runner's npm is too old for it + # Skipping an already published version lets a failed run be retried safely + # Waiting for the version to be installable keeps the GitHub release from getting ahead of npm - name: Publish package - run: npm publish + if: steps.check.outputs.release == 'true' + env: + DRY_RUN: ${{ inputs.dry-run }} + VERSION: ${{ steps.notes.outputs.version }} + run: | + name="$(jq -r .name package.json)" + if [[ "$DRY_RUN" == "true" ]]; then + pnpm publish --no-git-checks --dry-run + elif [[ -n "$(pnpm view "$name@${VERSION#v}" version 2>/dev/null)" ]]; then + echo "$name@${VERSION#v} is already published" + else + pnpm publish --no-git-checks --publish-wait-timeout 600000 + fi + + - name: Create GitHub release + if: steps.check.outputs.release == 'true' && !inputs.dry-run + env: + GH_TOKEN: ${{ github.token }} + NOTES: ${{ runner.temp }}/RELEASE_NOTES.md + VERSION: ${{ steps.notes.outputs.version }} + run: gh release create "$VERSION" --target "$GITHUB_SHA" --title "$VERSION" --notes-file "$NOTES" diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index 3b11aef..0000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1 +0,0 @@ -{".":"6.0.4"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 827f827..6e20f89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +> This file is no longer updated. Release notes for newer versions are published on the [GitHub Releases](https://github.com/forwardsoftware/react-native-toolbox/releases) page. + ## [6.0.4](https://github.com/forwardsoftware/react-native-toolbox/compare/v6.0.3...v6.0.4) (2026-09-08) diff --git a/README.md b/README.md index 53c30ba..a7e36dc 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,10 @@ EXAMPLES _See code: [src/commands/splash.ts](https://github.com/forwardsoftware/react-native-toolbox/blob/main/src/commands/splash.ts)_ +## Changelog + +Release notes for every version are published on the [GitHub Releases](https://github.com/forwardsoftware/react-native-toolbox/releases) page. + ## License Mozilla Public License 2.0 diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..d1ba505 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,36 @@ +# git-cliff configuration, see https://git-cliff.org/docs/configuration + +[changelog] +body = """ +{% for group, commits in commits | group_by(attribute="group") %} +### {{ group | striptags | trim }} +{% for commit in commits %} +- {% if commit.scope %}**{{ commit.scope }}:** {% endif %}{% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }} ({{ commit.id | truncate(length=7, end="") }})\ +{% endfor %} +{% endfor %} +""" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +filter_commits = true +protect_breaking_commits = true +tag_pattern = "^v[0-9]+\\.[0-9]+\\.[0-9]+$" +sort_commits = "newest" +# Only changes to shipped files count towards a release +exclude_paths = [".github/**", ".devcontainer/**", ".vscode/**", "cliff.toml"] +# Group names are prefixed with an HTML comment to control their order +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^docs", group = "Documentation" }, + { message = "^chore", group = "Miscellaneous" }, + { message = "^(ci|build|test|style)", skip = true }, +] + +[bump] +features_always_bump_minor = true +breaking_always_bump_major = true diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index 4538c6c..0000000 --- a/release-please-config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", - "release-type": "node", - "always-update": true, - "packages": { - ".": { - "include-component-in-tag": false - } - } -} \ No newline at end of file