determine_new_version() {
grep "version = " Cargo.toml | sed -Ee 's/version = "(.*)"/\1/' | head -1
}
determine_crate_name() {
grep "name = " Cargo.toml | sed -Ee 's/name = "(.*)"/\1/' | head -1
}
check_published_version() {
cirrus_agent="${CIRRUS_CI/?*/(Cirrus-CI)}"
final_agent="Release-Script/1.0 ${cirrus_agent:-(local)} (for $crate) (author:HeroicKatora)"
echo $final_agent
[[ $(wget -U "$final_agent" --content-on-error "https://crates.io/api/v1/crates/$crate/$new_version" -qO -) == "{\"errors\":"* ]] || {
published_commit=$(wget -U "$final_agent" "https://crates.io/api/v1/crates/$crate/$new_version/download" -qO - | tar xOzf - "$crate-$new_version/.cargo_vcs_info.json")
published_commit=$(sed 's/\"sha1\": \"\(.*\)\"/\1/;T0;p;:0;d' <<< "$published_commit")
echo "Already published at" "$published_commit"
}
}
git_considered_clean() {
[[ -z $(git status -s) ]]
}
count_wip_marker() {
[[ -z $(grep "\[WIP\]" Changes.md Readme.md) ]]
}
check_release_changes() {
[[ -z $(grep "# v$new_version" Changes.md) ]]
}
make_git_tag() {
tag_edit_msg="../.git/TAG_MSG_$(uuidgen)"
touch "$tag_edit_msg"
function cleanup() {
rm "$tag_edit_msg"
}
trap cleanup EXIT
echo $(pwd)
sed -e '0,/'"$new_version"'/d;/\#/,$d;/./,$!d' Changes.md >> "$tag_edit_msg"
echo >> "$tag_edit_msg"
sha256sum "../target/package/${crate}-${new_version}.crate" >> "$tag_edit_msg"
git tag -s -F "$tag_edit_msg" -e "${crate}-v${new_version}" $published_commit
}
is_force=""
do_tag=""
for param in $@
do
case "$param" in
-f) is_force="-f";;
--tag) do_tag="yes";;
--help) ;&
-h) { cat << EOF
usage: release [-f] [-h|--help] <version>
Automates checks and tagging of new releases. Encourages a workflow where
planned changes are integrated into readme and migration documentation early,
with WIP markers to help produce complete logs.
-f Force usage of version, even if such a tag already exists.
-h, --help Display this help
<version> A semantic version number matching [0-9a-zA-Z.-]*
EOF
exit 1; } ;;
esac
done
new_version="$(determine_new_version)"
crate="$(determine_crate_name)"
[[ -z $(grep -vE '[0-9a-zA-Z.-]*' <<< "$new_version" ) ]] || { echo "Fail: Check version number: ${new_version}"; exit 1; }
[[ -z "$crate" ]] && { echo "Couldn't determine crate name"; exit 1; }
git_considered_clean || { echo "Fail: Working directory is not clean"; exit 1; }
if [[ -f Contributors.txt ]]; then
if which parallel 2>/dev/null; then
{ (git shortlog -se | parallel -C '\t|<' grep -Fq -e '{2}' -e '\<{3}' Contributors.txt) || { echo "Fail: contributor not listed"; exit 1; }; }
else
{ echo "Checking contributors needs GNU parallel, please make sure manually." 1>&2; }
fi
fi
check_published_version || { echo "Version $new_version appears already published"; exit 1; }
count_wip_marker || { echo "Fail: Work in progress in documentation"; exit 1; }
check_release_changes && { echo "Fail: No changelog regarding this release"; exit 1; }
cargo package || { echo "Fail: cargo could not package successfully"; exit 1; }
[[ -z $do_tag ]] || make_git_tag