#!/bin/sh
# See license file for copyright and license details.

# release: automate creation of a new vX.Y.Z tag version and release.

set -e

progname="ytcast"
ghuser="MarcoLucidi01"
reltype="$1"
relbranch="master"
reldate="$(date +'%Y-%m-%d')"
relapiurl="https://api.github.com/repos/$ghuser/$progname/releases"
license="license"
readme="readme.md"
changelog="changelog.md"
changelogurl="https://github.com/$ghuser/$progname/blob/master/$changelog"
editorcmd="vim +8"
netrccmd="gpg --quiet --decrypt $HOME/.netrc.gpg" # for curl --netrc-file /dev/stdin

log() {
        printf "%s: " "$(date +'%H:%M:%S')" >&2
        echo "$@" >&2
}

die() {
        log "error:" "$@"
        exit 1
}

if [ "$reltype" != "major" ] && [ "$reltype" != "minor" ] && [ "$reltype" != "patch" ]; then
        die "unknown release type \"$reltype\"\nusage: ./release major|minor|patch"
elif [ "$(git branch --show-current)" != "$relbranch" ]; then
        die "current branch is not $relbranch"
elif [ -n "$(git status --short --porcelain)" ]; then
        die "working tree is not clean"
fi

currversion="$(git describe --tags --abbrev=0)"
if ! echo "$currversion" | grep -q '^v[0-9]\+\.[0-9]\+\.[0-9]\+$'; then
        die "\"$currversion\": current tag version does not match vX.Y.Z format"
fi
relversion="$(echo "$currversion" \
 | cut -c 2- \
 | awk -v "reltype=$reltype" '
    BEGIN { FS="."; OFS="." }
    { printf "%s", "v" }
    reltype == "major" { print $1+1, 0, 0 }
    reltype == "minor" { print $1, $2+1, 0 }
    reltype == "patch" { print $1, $2, $3+1 }
')"
log "new release version is $relversion"

sed "4i ## $relversion\n\n$reldate\n\n- WRITE CHANGELOG HERE (delete version to abort)\n" "$changelog" > "$changelog.tmp"
$editorcmd "$changelog.tmp"
if ! grep -q "^## $relversion$" "$changelog.tmp"; then
        die "changelog aborted"
fi
mv "$changelog.tmp" "$changelog"

log "committing $changelog and creating new tag $relversion"
git add "$changelog"
git commit --message="$changelog: $relversion"
git tag "$relversion"

echo "please make sure that everything is all right, --amend now if you have to."
while true; do
        printf "push to remote and create new release? [YES/NO] "
        read -r ans
        case "$ans" in
        "YES")
                break
                ;;
        "n" | "N" | "no" | "NO" | "No" | "nO")
                die "push aborted"
                ;;
        esac
done

log "building binaries"
make clean
make cross-build

log "creating archives"
mkdir "archive.tmp"
cp "$license" "$readme" "$changelog" "archive.tmp"
for binname in "$progname-$relversion-"*; do
        # this doesn't consider binary name extensions like .exe
        mv "$binname" "archive.tmp/$progname"
        mv "archive.tmp" "$binname"
        tar -czf "$binname.tar.gz" "$binname"
        sha256sum "$binname.tar.gz" >> "$progname-$relversion-sha256-checksums.txt"
        mv "$binname" "archive.tmp"
        log "created $binname.tar.gz"
done
rm -rf "archive.tmp"

log "pushing to remote"
git push
git push --tags

ghpost() {
        $netrccmd | curl --netrc-file /dev/stdin --silent --show-error --fail \
         -X POST \
         -H "Accept: application/vnd.github.v3+json" \
         -H "Content-Type: $1" \
         --data-binary "$2" \
         "$3"
}

log "creating new release with name $relversion"
reldata="$(jq -n -c --arg relversion "$relversion" --arg changelogurl "$changelogurl" \
'{
    "tag_name": $relversion,
    "name": $relversion,
    "body": "[changelog](\($changelogurl)#\($relversion | gsub("\\."; "")))"
}')"
relinfo="$(ghpost "application/json" "$reldata" "$relapiurl")"
log "created new release $(echo "$relinfo" | jq -r '.html_url')"

reluploadurl="$(echo "$relinfo" | jq -r '.upload_url' | sed 's/{.*$//')"
for asset in "$progname-$relversion-"*".tar.gz" "$progname-$relversion-"*"-checksums.txt"; do
        log "uploading $asset"
        assetinfo="$(ghpost "$(file --brief --mime-type "$asset")" "@$asset" "$reluploadurl?name=$asset")"
        log "uploaded $(echo "$assetinfo" | jq -r '.browser_download_url')"
done

log "done!"
