From 0079bcb471a6d260bb06ef51ff495ec1c6cdcc2f Mon Sep 17 00:00:00 2001 From: limiting-factor Date: Sun, 23 Feb 2025 16:03:14 +0100 Subject: [PATCH] fix: override=true must not needlessly delete a tag If the tag to be set is exactly the same as the tag that exists, do not delete it. When the tag is recreated although it is not necessary, it may trigger workflows that have already been triggered and send the workflow in a loop. - split `get_tag` & `matched_tag` out of ensure_tag - in case of an override, only delete the tag if it fails `matched_tag` - trace shell lines to help debug - add testing --- forgejo-release.sh | 37 ++++++++++++++++++++++++++------ testdata/forgejo-release-test.sh | 7 ++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/forgejo-release.sh b/forgejo-release.sh index 20d5221..1474b6a 100755 --- a/forgejo-release.sh +++ b/forgejo-release.sh @@ -19,6 +19,8 @@ if ${VERBOSE:-false}; then set -x; fi : ${RETRY:=1} : ${DELAY:=10} +TAG_FILE="$TMP_DIR/tag$$.json" + export GNUPGHOME setup_tea() { @@ -29,16 +31,35 @@ setup_tea() { fi } +get_tag() { + if ! test -f "$TAG_FILE"; then + if api GET repos/$REPO/tags/"$TAG" >"$TAG_FILE"; then + echo "tag $TAG exists" + else + echo "tag $TAG does not exists" + fi + fi + test -s "$TAG_FILE" +} + +matched_tag() { + if get_tag; then + local sha=$(jq --raw-output .commit.sha <"$TAG_FILE") + test "$sha" = "$SHA" + else + return 1 + fi +} + ensure_tag() { - if api GET repos/$REPO/tags/"$TAG" >"$TMP_DIR"/tag.json; then - local sha=$(jq --raw-output .commit.sha <"$TMP_DIR"/tag.json) - if test "$sha" != "$SHA"; then - cat "$TMP_DIR"/tag.json + if get_tag; then + if ! matched_tag; then + cat "$TAG_FILE" echo "the tag SHA in the $REPO repository does not match the tag SHA that triggered the build: $SHA" - false + return 1 fi else - api POST repos/$REPO/tags --data-raw '{"tag_name": "'"$TAG"'", "target": "'"$SHA"'"}' + api POST repos/$REPO/tags --data-raw '{"tag_name": "'"$TAG"'", "target": "'"$SHA"'"}' >"$TAG_FILE" fi } @@ -112,7 +133,9 @@ maybe_override() { return fi api DELETE repos/$REPO/releases/tags/"$TAG" >&/dev/null || true - api DELETE repos/$REPO/tags/"$TAG" >&/dev/null || true + if get_tag && ! matched_tag; then + api DELETE repos/$REPO/tags/"$TAG" + fi } upload() { diff --git a/testdata/forgejo-release-test.sh b/testdata/forgejo-release-test.sh index 4ff2eae..97f630c 100755 --- a/testdata/forgejo-release-test.sh +++ b/testdata/forgejo-release-test.sh @@ -45,15 +45,18 @@ test_ensure_tag() { # idempotent # ensure_tag - api GET repos/$REPO/tags/$TAG >$TMP_DIR/tag1.json + mv $TAG_FILE $TMP_DIR/tag1.json + ensure_tag - api GET repos/$REPO/tags/$TAG >$TMP_DIR/tag2.json + mv $TAG_FILE $TMP_DIR/tag2.json + diff -u $TMP_DIR/tag[12].json # # sanity check on the SHA of an existing tag # ( SHA=12345 + ! matched_tag ! ensure_tag ) api DELETE repos/$REPO/tags/$TAG