diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe0014c..054443f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,18 +36,30 @@ jobs: persist-credentials: false - run: shellcheck scripts/*.sh + # The version in plugin.json must have a non-empty CHANGELOG.md section (what the release needs). + changelog: + runs-on: ubuntu-24.04 + timeout-minutes: 5 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - run: scripts/release-notes.sh HEAD "v$(jq -r .version plugin.json)" >/dev/null + # The one check the main ruleset requires. It passes only when every gate succeeded. required: name: required - needs: [qml, shellcheck] + needs: [qml, shellcheck, changelog] if: always() runs-on: ubuntu-24.04 timeout-minutes: 5 env: QML: ${{ needs.qml.result }} SHELLCHECK: ${{ needs.shellcheck.result }} + CHANGELOG: ${{ needs.changelog.result }} steps: - run: | - echo "qml=$QML shellcheck=$SHELLCHECK" + echo "qml=$QML shellcheck=$SHELLCHECK changelog=$CHANGELOG" test "$QML" = success test "$SHELLCHECK" = success + test "$CHANGELOG" = success diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 759863f..234cc7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,7 +54,12 @@ jobs: scripts/release-green.sh "$sha" scripts/release-notes.sh "$sha" "$TAG" > notes.md if [ "$GITHUB_EVENT_NAME" = workflow_dispatch ]; then - echo "Dry run: would create release $TAG on $sha with these notes, nothing created:" + if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null || + gh release view "$TAG" >/dev/null 2>&1; then + echo "Dry run: the tag or a release $TAG already exists; a tag push would not create anything new. The checks passed for $sha; nothing created. Notes it would have:" + else + echo "Dry run: would create release $TAG on $sha with these notes, nothing created:" + fi else echo "Checks passed: release $TAG on $sha with these notes:" fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b9e65f..2bb7e1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,9 @@ the change) are credited at the end of their line as `(#N, thanks @handle)`. `main` (#132). - A tag `vX.Y.Z` now creates the GitHub release by workflow. It first checks that the tag equals the `plugin.json` version, that the commit is on `main` and was green as a pull request, and that - `CHANGELOG.md` has a section for the version; the release notes are that section (#138). + `CHANGELOG.md` has a section for the version; the release notes are that section (#138). A dry run says when the + tag or release already exists. CI checks that the `plugin.json` version has a CHANGELOG section + (#140). ### Changed diff --git a/README.md b/README.md index 1f97912..b69a4c7 100644 --- a/README.md +++ b/README.md @@ -188,12 +188,13 @@ Tiny 2 Lite. 1. Land a commit "Release X.Y.Z" through a pull request: it sets `version` in `plugin.json` and turns the `## [Unreleased]` entries of `CHANGELOG.md` into a `## [X.Y.Z] - date` section. -2. Push the signed tag `vX.Y.Z` on that commit. The Release workflow creates the GitHub release, +2. Dry run: run the Release workflow by hand with that commit and the version; it runs the checks + and prints the release it would create, and creates nothing. Do this before the tag: tags `v*` + cannot be moved or deleted in this repository, so a tag on a bad release commit burns the version. +3. Push the signed tag `vX.Y.Z` on that commit. The Release workflow creates the GitHub release, with that CHANGELOG section as notes, after it has checked that the tag equals the `plugin.json` version, that the commit is on `main` and was green as a pull request, and that the section exists. If a check fails, no release is created. -3. Dry run: run the Release workflow by hand with a commit and a version; it runs the checks and - prints the release it would create. ## License