#!/bin/sh { set -ex version=$1 repository_owner=fish-shell remote=origin if [ -n "$2" ]; then set -u repository_owner=$2 remote=$3 set +u [ $# -eq 3 ] fi [ -n "$version" ] for tool in \ bundle \ gh \ ruby \ timeout \ ; do if ! command -v "$tool" >/dev/null; then echo >&2 "$0: missing command: $1" exit 1 fi done repo_root="$(dirname "$0")/.." fish_site=$repo_root/../fish-site for path in . "$fish_site" do if ! git -C "$path" diff HEAD --quiet; then echo >&2 "$0: index and worktree must be clean" exit 1 fi done if git tag | grep -qxF "$version"; then echo >&2 "$0: tag $version already exists" exit 1 fi sed -n 1p CHANGELOG.rst | grep -q '^fish .*(released ???)$' sed -n 2p CHANGELOG.rst | grep -q '^===*$' changelog_title="fish $version (released $(date +'%B %d, %Y'))" sed -i \ -e "1c$changelog_title" \ -e "2c$(printf %s "$changelog_title" | sed s/./=/g)" \ CHANGELOG.rst CommitVersion() { sed -i "s/^version = \".*\"/version = \"$1\"/g" Cargo.toml cargo fetch --offline git add CHANGELOG.rst Cargo.toml Cargo.lock git commit -m "$2 Created by ./build_tools/release.sh $version" } CommitVersion "$version" "Release $version" # N.B. this is not GPG-signed. git tag --annotate --message="Release $version" $version git push $remote $version gh() { command gh --repo "$repository_owner/fish-shell" "$@" } run_id= while [ -z "$run_id" ] && sleep 5 do run_id=$(gh run list \ --json=databaseId --jq=.[].databaseId \ --workflow=release.yml --limit=1 \ --commit="$(git rev-parse "$version^{commit}")") done # Update fishshell.com tag_oid=$(git rev-parse "$version") tmpdir=$(mktemp -d) while ! \ gh release download "$version" --dir="$tmpdir" \ --pattern="fish-$version.tar.xz" do timeout 30 gh run watch "$run_id" ||: done actual_tag_oid=$(git ls-remote "$remote" | awk '$2 == "refs/tags/'"$version"'" { print $1 }') [ "$tag_oid" = "$actual_tag_oid" ] tar -C "$tmpdir" xf fish-$version.tar.xz minor_version=${version%.*} CopyDocs() { rm -rf "fish-site/site/docs/$1" cp -r "$tmpdir/fish-$version/user_doc/html" "fish-site/site/docs/$1" git -C fish-site add "site/docs/$1" } CopyDocs "$minor_version" latest_release=$( releases=$(git tag | grep '^[0-9]*\.[0-9]*\.[0-9]*.*' | sed $(: "De-prioritize release candidates (1.2.3-rc0)") \ 's/-/~/g' | LC_ALL=C sort --version-sort) printf %s\\n "$releases" | tail -1 ) if [ "$version" = "$latest_release" ]; then CopyDocs current fi rm -rf "$tmpdir" ( cd "$fish_site" make new-release git add -u git commit --message="$(printf %s "\ | Release $version | | Created by ../fish-shell/build_tools/release.sh " | sed 's,^\s*| ,,')" ) # N.B. --exit-status doesn't fail reliably. gh run view "$run_id" --verbose --log-failed --exit-status while { ! draft=$(gh release view "$version" --json=isDraft --jq=.isDraft) \ || [ "$draft" = true ] } do sleep 20 done ( cd "$fish_site" git push git@github.com:$repository_owner/fish-site ) if git merge-base --is-ancestor $remote/master $version then git push $remote $version:master else # Probably on an integration branch. # TODO Maybe push when that's safe (or move this to CI). : fi if [ "$repository_owner" = fish-shell ]; then { mail=$(mktemp) cat >$mail < Subject: fish $version released See https://github.com/fish-shell/fish-shell/releases/tag/$version EOF git send-email --suppress-cc=all $mail rm $mail } fi changelog=$(cat - CHANGELOG.rst <CHANGELOG.rst CommitVersion ${version}-snapshot "start new cycle" exit }