From db64236f85cf78504796a9354ed776c31ca88f5e Mon Sep 17 00:00:00 2001 From: Twenty Panda Date: Tue, 23 Jul 2024 16:45:44 +0200 Subject: [PATCH] feat(release-notes-assistant): if no labels, fallback to prefix * support feat: fix: feat!: fix! conventional commits prefixes * add unit tests --- .../workflows/release-notes-assistant.yml | 1 + .forgejo/workflows/testing.yml | 4 + release-notes-assistant.sh | 276 ++++++++++++++---- 3 files changed, 227 insertions(+), 54 deletions(-) diff --git a/.forgejo/workflows/release-notes-assistant.yml b/.forgejo/workflows/release-notes-assistant.yml index 81e63238b2..9fa7b22ec2 100644 --- a/.forgejo/workflows/release-notes-assistant.yml +++ b/.forgejo/workflows/release-notes-assistant.yml @@ -19,6 +19,7 @@ jobs: - uses: https://code.forgejo.org/actions/setup-go@v4 with: go-version-file: "go.mod" + cache: false - name: apt install jq run: | diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index e2a41f72ee..d6c127a355 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -75,6 +75,10 @@ jobs: apt-get -q install -qq -y git rm /etc/apt/sources.list.d/testing.list apt-get update -qq + - name: test release-notes-assistant.sh + run: | + apt-get -q install -qq -y jq + ./release-notes-assistant.sh test_main - run: | su forgejo -c 'make deps-backend' - run: | diff --git a/release-notes-assistant.sh b/release-notes-assistant.sh index 4e15975340..fd8570d988 100755 --- a/release-notes-assistant.sh +++ b/release-notes-assistant.sh @@ -2,72 +2,240 @@ # Copyright twenty-panda # SPDX-License-Identifier: MIT +label_worth=worth +label_bug=bug +label_feature=feature +label_ui=forgejo/ui +label_breaking=breaking + payload=$(mktemp) pr=$(mktemp) trap "rm $payload $pr" EXIT -cat >$payload -# -# If this is a backport, refer to the original PR to figure -# out the classification. -# -if $(jq --raw-output .IsBackportedFrom <$payload); then - jq --raw-output '.BackportedFrom[0]' <$payload >$pr -else - jq --raw-output '.Pr' <$payload >$pr -fi +function test_main() { + set -ex + PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: ' -labels=$(jq --raw-output '.labels[].name' <$pr) + test_payload_labels $label_worth $label_breaking $label_feature + test "$(categorize)" = 'AA Breaking features' -# -# Was this PR labeled `worth a release note`? -# -if echo "$labels" | grep --quiet worth; then - worth=true -else - worth=false -fi + test_payload_labels $label_worth $label_breaking $label_bug + test "$(categorize)" = 'AB Breaking bug fixes' -# -# If there was no release-notes/N.md file and it is not -# worth a release note, just forget about it. -# -if test -z "$(jq --raw-output .Draft <$payload)"; then - if ! $worth; then - echo -n ZA Included for completness but not worth a release note - exit 0 + test_payload_labels $label_worth $label_breaking + test "$(categorize)" = 'ZC Breaking changes without a feature or bug label' + + test_payload_labels $label_worth $label_ui $label_feature + test "$(categorize)" = 'BA User Interface features' + + test_payload_labels $label_worth $label_ui $label_bug + test "$(categorize)" = 'BB User Interface bug fixes' + + test_payload_labels $label_worth $label_ui + test "$(categorize)" = 'ZD User Interface changes without a feature or bug label' + + test_payload_labels $label_worth $label_feature + test "$(categorize)" = 'CA Features' + + test_payload_labels $label_worth $label_bug + test "$(categorize)" = 'CB Bug fixes' + + test_payload_labels $label_worth + test "$(categorize)" = 'ZE Other changes without a feature or bug label' + + test_payload_labels + test "$(categorize)" = 'ZF Included for completness but not worth a release note' + + test_payload_draft "feat!: breaking feature" + test "$(categorize)" = 'AA Breaking features' + + test_payload_draft "fix!: breaking bug fix" + test "$(categorize)" = 'AB Breaking bug fixes' + + test_payload_draft "feat: feature" + test "$(categorize)" = 'CA Features' + + test_payload_draft "fix: bug fix" + test "$(categorize)" = 'CB Bug fixes' + + test_payload_draft "something with no prefix" + test "$(categorize)" = 'ZE Other changes without a feature or bug label' +} + +function main() { + cat >$payload + categorize +} + +function categorize() { + # + # If this is a backport, refer to the original PR to figure + # out the classification. + # + if $(jq --raw-output .IsBackportedFrom <$payload); then + jq --raw-output '.BackportedFrom[0]' <$payload >$pr + else + jq --raw-output '.Pr' <$payload >$pr fi -fi -case "$labels" in -*bug*) - if $(jq --raw-output .IsBackportedTo <$payload); then - # - # if it has been backported, it was in the release notes of an older stable release - # and does not need to be in this more recent release notes - # - echo -n ZB Already announced in the release notes of an older stable release - exit 0 + labels=$(jq --raw-output '.labels[].name' <$pr) + + # + # Was this PR labeled `worth a release note`? + # + if echo "$labels" | grep --quiet $label_worth; then + worth=true + else + worth=false fi - ;; -esac -case "$labels" in -*breaking*) + # + # If there was no release-notes/N.md file and it is not + # worth a release note, just forget about it. + # + if test -z "$(jq --raw-output .Draft <$payload)"; then + if ! $worth; then + echo -n ZF Included for completness but not worth a release note + exit 0 + fi + fi + + is_ui=false + is_bug=false + is_feature=false + is_breaking=false + + # + # first try to figure out the category from the labels + # case "$labels" in - *feature*) echo -n AA Breaking features ;; - *bug*) echo -n AB Breaking bug fixes ;; - *) echo -n ZC Breaking changes without a feature or bug label ;; + *$label_bug*) + is_bug=true + ;; + *$label_feature*) + is_feature=true + ;; esac - ;; -*forgejo/ui*) + case "$labels" in - *feature*) echo -n BA User Interface features ;; - *bug*) echo -n BB User Interface bug fixes ;; - *) echo -n ZD User Interface changes without a feature or bug label ;; + *$label_breaking*) + is_breaking=true + ;; esac - ;; -*feature*) echo -n CA Features ;; -*bug*) echo -n CB Bug fixes ;; -*) echo -n ZE Other changes without a feature or bug label ;; -esac + + case "$labels" in + *$label_ui*) + is_ui=true + ;; + esac + + # + # then try the prefix of the release note + # + if ! $is_bug && ! $is_feature; then + draft="$(jq --raw-output .Draft <$payload)" + case "$draft" in + fix!:*) + is_bug=true + is_breaking=true + ;; + fix:*) + is_bug=true + ;; + feat!:*) + is_feature=true + is_breaking=true + ;; + feat:*) + is_feature=true + ;; + esac + fi + + if $is_bug; then + if $(jq --raw-output .IsBackportedTo <$payload); then + # + # if it has been backported, it was in the release notes of an older stable release + # and does not need to be in this more recent release notes + # + echo -n ZG Already announced in the release notes of an older stable release + exit 0 + fi + fi + + if $is_breaking; then + if $is_feature; then + echo -n AA Breaking features + elif $is_bug; then + echo AB Breaking bug fixes + else + echo -n ZC Breaking changes without a feature or bug label + fi + elif $is_ui; then + if $is_feature; then + echo -n BA User Interface features + elif $is_bug; then + echo -n BB User Interface bug fixes + else + echo -n ZD User Interface changes without a feature or bug label + fi + else + if $is_feature; then + echo -n CA Features + elif $is_bug; then + echo -n CB Bug fixes + else + echo -n ZE Other changes without a feature or bug label + fi + fi +} + +function test_payload_labels() { + local label1="$1" + local label2="$2" + local label3="$3" + local label4="$4" + + cat >$payload <$payload <