Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 6 additions & 18 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Mostly copied from https://github.com/taiki-e/cargo-hack/blob/72a9fc95377c453a18026329577c59fa60bfa737/.github/workflows/release.yml
# Mostly copied from https://github.com/taiki-e/cargo-hack/blob/main/.github/workflows/release.yml
name: Release

permissions:
# TODO: once `releases: write` is supported, use it instead.
contents: write
contents: read

on:
push:
Expand All @@ -12,31 +11,20 @@ on:

env:
CARGO_INCREMENTAL: 0
CARGO_NET_GIT_FETCH_WITH_CLI: true
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
RUSTFLAGS: -D warnings
RUSTUP_MAX_RETRIES: 10

defaults:
run:
# Setting shell: bash explicitly activates pipefail
shell: bash

jobs:
create-release:
if: github.repository_owner == 'danielparks'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Install Rust
run: rustup update stable --no-self-update
- run: cargo package
- uses: taiki-e/create-gh-release-action@v1
- uses: danielparks/github-actions/create-release@main
with:
changelog: CHANGELOG.md
title: Release $version
branch: main
token: ${{ secrets.GITHUB_TOKEN }}
124 changes: 100 additions & 24 deletions release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -eo pipefail
shopt -s extglob

version=$1
branch_name=$(git rev-parse --abbrev-ref HEAD)

awk-in-place () {
local tmpfile=$(mktemp)
Expand All @@ -14,6 +15,51 @@ awk-in-place () {
rm "$tmpfile"
}

check-changes () {
if git ls-files --exclude-standard --other | grep . >/dev/null ; then
echo 'Found untracked files:' >&2
git ls-files --exclude-standard --other | sed -e 's/^/ /' >&2
echo >&2
echo 'Please commit changes before proceeding.' >&2
return 1
fi

git diff --color --exit-code HEAD || {
echo >&2
echo 'Please commit changes before proceeding.' >&2
return 1
}
}

crate-names () {
cargo metadata --format-version 1 --no-deps | jq -r '.packages[].name'
}

auto-pr () {
pr_url=$((gh pr view --json url,closed 2>/dev/null || true) \
| jq -r 'select(.closed | not) | .url')

if [[ "$pr_url" ]] ; then
echo "Found existing PR: $pr_url"
echo
else
# Create a PR
gh pr create --fill-verbose --title "$1"
fi

gh pr merge --disable-auto --delete-branch
sleep 3
gh pr checks --watch --fail-fast

git checkout main
git pull
git merge --ff-only "$branch_name"
git push origin HEAD

git branch -d "$branch_name"
git push origin --delete "$branch_name"
}

confirm () {
local prompt="$1"
local answer
Expand All @@ -25,10 +71,31 @@ confirm () {
}

case $version in
+([0-9]).+([0-9]).+([0-9])) ;; # Good
+([0-9]).+([0-9]).+([0-9])*) ;; # Good
*) echo "Usage $0 VERSION" >&2 ; exit 1 ;;
esac

command -v gh &>/dev/null || {
echo "gh not installed (https://cli.github.com)" >&2
exit 1
}

command -v jq &>/dev/null || {
echo "jq not installed (https://jqlang.org)" >&2
exit 1
}

command -v parse-changelog &>/dev/null || {
echo "parse-changelog not installed (https://github.com/taiki-e/parse-changelog)" >&2
exit 1
}

if [[ "$branch_name" = main ]] ; then
git switch -c "release-$version"
fi

check-changes

echo 'Making sure version is correct.'

awk-in-place Cargo.toml '
Expand All @@ -38,14 +105,22 @@ awk-in-place Cargo.toml '
}
{ print }'

awk-in-place README.md '{
sub(/https:\/\/docs\.rs\/htmlize\/[0-9]+.[0-9]+.[0-9]+\//, "https://docs.rs/htmlize/'$version'/")
print
}'
# Fix docs.rs links in README, if present
for name in $(crate-names) ; do
awk-in-place README.md '{
sub(/https:\/\/docs\.rs\/'"$name"'\/[0-9]+.[0-9]+.[0-9]+\//, \
"https://docs.rs/'"$name"'/'$version'/")
print
}'
done

cargo check --quiet

cargo semver-checks check-release
# Do semver checks only if there is a version on crates.io to compare to.
# FIXME: can’t tell if crates.io search failed for another reason.
if (cd / && cargo info "$(crate-names | head -1)" &>/dev/null) ; then
cargo semver-checks || { echo ; confirm 'Release anyway?' ; }
fi

awk-in-place CHANGELOG.md '
/^## / && !done {
Expand All @@ -54,21 +129,6 @@ awk-in-place CHANGELOG.md '
}
{ print }'

# Check for changes
if git ls-files --exclude-standard --other | grep . >/dev/null ; then
echo 'Found untracked files:' >&2
git ls-files --exclude-standard --other | sed -e 's/^/ /' >&2
echo >&2
echo 'Please commit changes before proceeding.' >&2
exit 1
fi

git diff --color --exit-code HEAD || {
echo >&2
echo 'Please commit changes before proceeding.' >&2
exit 1
}

# Confirm changelog
changelog=$(mktemp)
{
Expand All @@ -81,10 +141,23 @@ cat "$changelog"
echo
confirm 'Release notes displayed above. Continue?'

cargo publish
# Commit version bump if necessary.
check-changes &>/dev/null || {
git add -u
git commit --cleanup=verbatim --file - <<EOF
Release ${version}

$(parse-changelog CHANGELOG.md "$version")
EOF
}

check-changes

git tag --sign --file "$changelog" --cleanup=verbatim "v${version}"
git push --tags origin main
git tag --force --sign --file "$changelog" --cleanup=verbatim "v${version}"
git push --force --tags origin HEAD
auto-pr "Release ${version}"

cargo publish

awk-in-place CHANGELOG.md '
/^## Release/ && !done {
Expand All @@ -93,9 +166,12 @@ awk-in-place CHANGELOG.md '
}
{ print }'

git switch -c post-release
git add CHANGELOG.md
git diff --staged

confirm 'Commit with message "Prepping CHANGELOG.md for development."?'

git commit -m 'Prepping CHANGELOG.md for development.'
git push --force origin HEAD
auto-pr "Prepping CHANGELOG.md for development"
Loading