git-sumi 0.0.1

Non-opinionated commit message linter
Documentation
#!/usr/bin/env bash
# Bash script to prepare a release using git-cliff.
# Inspired by https://github.com/orhun/git-cliff/blob/main/release.sh
set -eu

# Check if a version tag is provided.
if [ "$#" -eq 1 ]; then
    VERSION_TAG=$1
else
    # After git-cliff version 1.4.0 it should be possible to run `git cliff --bumped-version`.
    suggested_version=$(git cliff --unreleased --bump --context | jq -r .[0].version)
    echo -n "No version tag provided. git-cliff suggests $suggested_version. Proceed? [Y/n] "
    read user_input

    # Check if input is empty or a variation of "yes".
    if [[ -z "$user_input" || "$user_input" =~ ^[Yy](es)?$ ]]; then
        echo "Proceeding with version $suggested_version."
        VERSION_TAG=$suggested_version
    else
        echo "Release preparation cancelled."
        exit 1
    fi
fi

# Update CHANGELOG.
git cliff --tag "$VERSION_TAG" -o CHANGELOG.md

# Add all changes and commit.
git add -A
git commit -m "🔖 chore(release): prepare for $VERSION_TAG"

# Template for the tag description.
export GIT_CLIFF_TEMPLATE="\
    {%- set breaking_header_shown = false -%}
    {% for commit in commits -%}
        {%- if commit.breaking and not breaking_header_shown %}
            💥 BREAKING CHANGES 💥
            {% set_global breaking_header_shown = true -%}
        {%- endif %}
        {%- if commit.breaking %}
            - {{ commit.message | upper_first -}}
        {% endif -%}
    {% endfor %}
    {% for group, group_commits in commits | group_by(attribute=\"group\") %}
        {{ group | striptags | trim | upper_first }}
        {% for commit in group_commits %}
            - {% if commit.breaking %}[‼️BREAKING‼️] {% endif %}{{ commit.message | upper_first }}
        {%- endfor %}
    {% endfor %}"

# Cleaner template for the tag description.
export GIT_CLIFF__CHANGELOG__BODY=$(cat <<'EOF'
{% if version %}\
    ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
    ## unreleased
{% endif %}\

{% macro commit(commit, in_breaking_section=false) -%}
    - {% if commit.scope %}*({{ commit.scope }})* {% endif %}{% if commit.breaking and not in_breaking_section %}[**‼️BREAKING‼️**] {% endif %}\
        {{ commit.message | upper_first }} - ({{ commit.id | truncate(length=7, end="") }})\
{% endmacro -%}

{%- set breaking_header_shown = false -%}
{% for commit in commits -%}
    {% if commit.breaking and not breaking_header_shown -%}
        {% raw %}\n### 💥 BREAKING CHANGES 💥\n{% endraw %}
        {% set_global breaking_header_shown = true %}
    {%- endif -%}
    {%- if commit.breaking -%}
        {{ self::commit(commit=commit, in_breaking_section=true) -}}
    {% endif -%}
{%- endfor -%}
{%- if breaking_header_shown == true -%}
    {% raw %}\n{% endraw %}\
{%- endif -%}

{% for group, commits in commits | group_by(attribute="group") %}
    ### {{ group | striptags | trim | upper_first }}
    {% for commit in commits
    | filter(attribute="scope")
    | sort(attribute="scope") %}
        {{ self::commit(commit=commit) }}
    {%- endfor -%}
    {% raw %}\n{% endraw %}\
    {%- for commit in commits %}
        {%- if not commit.scope -%}
            {{ self::commit(commit=commit) }}
        {% endif -%}
    {% endfor -%}
{% endfor %}\n
EOF
)

# Same as cliff.toml, except we don't replace issue number with a link (which aren't clickable on tag descriptions).
export GIT_CLIFF__GIT__PREPROCESSORS=$(cat <<'EOF'
# Remove trailing whitespace.
{ pattern = ' +$', replace = "" },
# Replace multiple spaces with a single space.
{ pattern = ' +', replace = " " },
# Remove gitmoji, both actual UTF emoji and :emoji:
{ pattern = ' *(:\w+:|[\p{Emoji_Presentation}\p{Extended_Pictographic}\u{200D}]) *', replace = "" }
EOF
)

# Generate the tag description.
changelog=$(git cliff --tag "$VERSION_TAG" --unreleased --strip all)

# Create a signed and annotated tag.
git tag -s -a "$VERSION_TAG" -m "Release $VERSION_TAG" -m "$changelog"

echo "Most recent commit:"
git log -1
echo
echo "Information for tag $VERSION_TAG:"
git show $VERSION_TAG
echo

echo "Release $VERSION_TAG is ready. Don't forget to push the changes and the tag:"
echo "git push && git push --tags"
echo
echo "Once that's done, you should see your tag on GitHub:"

remote_url=$(git remote get-url origin)

# Check if the URL is in SSH format (git@).
if [[ "$remote_url" == git@github.com:* ]]; then
    https_url="https://github.com/${remote_url#git@github.com:}"
    https_url="${https_url%.git}"
else
    https_url="${remote_url%.git}"
fi

echo "${https_url}/tags"

echo "To publish on PyPI, run:"
echo "cd pypi && maturin publish --frozen"