name: Release
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 0.1.1) - required for manual trigger'
required: true
type: string
permissions:
contents: write
packages: write
env:
CARGO_TERM_COLOR: always
jobs:
build-linux:
name: Build Linux (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain*') }}
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.target }}
path: target/${{ matrix.target }}/release/rco
retention-days: 5
build:
name: Build (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install OpenSSL (macOS)
if: matrix.target == 'x86_64-apple-darwin' || matrix.target == 'aarch64-apple-darwin'
run: |
brew install openssl
echo "OPENSSL_LIB_DIR=$(brew --prefix openssl)/lib" >> "$GITHUB_ENV"
echo "OPENSSL_INCLUDE_DIR=$(brew --prefix openssl)/include" >> "$GITHUB_ENV"
- name: Install OpenSSL (Windows)
if: matrix.target == 'x86_64-pc-windows-msvc'
run: |
choco install openssl -y
echo "OPENSSL_DIR=C:\Program Files\OpenSSL" >> "$GITHUB_ENV"
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain*') }}
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.target }}
path: target/${{ matrix.target }}/release/rco${{ matrix.target == 'x86_64-pc-windows-msvc' && '.exe' || '' }}
retention-days: 5
release:
name: Create Release
needs:
- build
- build-linux
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download all binaries
uses: actions/download-artifact@v4
with:
path: binaries
pattern: binary-*
merge-multiple: false
- name: Determine version
id: version
run: |
VERSION_RAW="${{ github.event.inputs.version || github.ref_name }}"
VERSION="${VERSION_RAW#v}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Prepare release assets
run: |
VERSION="${{ steps.version.outputs.version }}"
mkdir -p release
for dir in binaries/binary-*; do
target=$(basename "$dir" | sed 's/binary-//')
case "$target" in
x86_64-pc-windows-msvc)
if [ -f "$dir/rco.exe" ]; then
(cd "$dir" && zip -r "$GITHUB_WORKSPACE/release/rusty-commit-v${VERSION}-${target}.zip" rco.exe)
fi
;;
*)
if [ -f "$dir/rco" ]; then
tmpdir=$(mktemp -d)
cp "$dir/rco" "$tmpdir/rco"
tar -C "$tmpdir" -czf "release/rusty-commit-v${VERSION}-${target}.tar.gz" .
rm -rf "$tmpdir"
fi
;;
esac
done
ls -la release
- name: Create GitHub Release
uses: softprops/action-gh-release@v2.5.0
with:
draft: false
prerelease: false
generate_release_notes: true
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
files: release/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload release binaries for finalize job
uses: actions/upload-artifact@v4
with:
name: release
path: release/
retention-days: 5
publish-crates:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain*') }}
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
if [ -n "$CARGO_REGISTRY_TOKEN" ]; then
cargo publish --registry crates-io --allow-dirty
else
echo "CARGO_REGISTRY_TOKEN not set, skipping crates.io publish"
fi
build-deb:
name: Build Debian Package (${{ matrix.arch }})
needs: build-linux
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-latest
target: x86_64-unknown-linux-gnu
deb_arch: amd64
- arch: arm64
runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
deb_arch: arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain*') }}
- name: Install cargo-deb
uses: taiki-e/install-action@v2
with:
tool: cargo-deb
- name: Download release binary
uses: actions/download-artifact@v4
with:
name: binary-${{ matrix.target }}
path: target/${{ matrix.target }}/release
- name: Build .deb package
run: cargo deb --target ${{ matrix.target }} --no-build
- name: Upload .deb package
uses: actions/upload-artifact@v4
with:
name: rusty-commit.deb-${{ matrix.arch }}
path: target/${{ matrix.target }}/debian/*_${{ matrix.deb_arch }}.deb
build-rpm:
name: Build RedHat Package (${{ matrix.arch }})
needs: build-linux
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-latest
target: x86_64-unknown-linux-gnu
rpm_arch: x86_64
- arch: arm64
runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
rpm_arch: aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download release binary
uses: actions/download-artifact@v4
with:
name: binary-${{ matrix.target }}
path: target/${{ matrix.target }}/release
- name: Install rpm build tools
run: |
sudo apt-get update
sudo apt-get install -y rpm
- name: Create RPM structure
run: |
VERSION="${{ github.event.inputs.version || github.ref_name }}"
VERSION="${VERSION#v}"
pkgname="rusty-commit"
mkdir -p rpmbuild/BUILD rpmbuild/BUILDROOT rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SPECS rpmbuild/SRPMS
# Create tarball with proper directory structure (tarball name without .tar.gz must match extracted dir)
mkdir -p "tmp-pkg-dir/${pkgname}-${VERSION}"
cp target/${{ matrix.target }}/release/rco "tmp-pkg-dir/${pkgname}-${VERSION}/"
tar -C tmp-pkg-dir -czf "rpmbuild/SOURCES/${pkgname}-${VERSION}.tar.gz" "${pkgname}-${VERSION}"
rm -rf tmp-pkg-dir
# Create spec file
cat > rpmbuild/SPECS/rusty-commit.spec << EOF
Name: ${pkgname}
Version: ${VERSION}
Release: 0%{?dist}
Summary: A modern, AI-powered git commit message generator
License: MIT
URL: https://github.com/hongkongkiwi/rusty-commit
Source0: %{name}-%{version}.tar.gz
BuildArch: ${{ matrix.rpm_arch }}
%description
Rusty-commit is a modern, AI-powered git commit message generator that helps
you create meaningful, standardized commit messages following Conventional Commits.
%prep
%setup -q
%install
mkdir -p %{buildroot}/usr/bin
install -m 755 %{_builddir}/%{name}-%{version}/rco %{buildroot}/usr/bin/rco
%files
/usr/bin/rco
%changelog
* Sat Jan 24 2026 Rusty Commit <rusty-commit@users.noreply.github.com> - ${VERSION}-0
- Initial RPM package
EOF
- name: Build .rpm package
run: |
rpmbuild --define "_topdir $PWD/rpmbuild" \
-bb rpmbuild/SPECS/rusty-commit.spec \
--target ${{ matrix.rpm_arch }}
- name: Upload .rpm package
uses: actions/upload-artifact@v4
with:
name: rusty-commit.rpm-${{ matrix.arch }}
path: rpmbuild/RPMS/${{ matrix.rpm_arch }}/*.rpm
build-apk:
name: Build Alpine Package (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-latest
target: x86_64-unknown-linux-musl
apk_arch: x86_64
- arch: arm64
runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
apk_arch: aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU for Docker
if: matrix.arch == 'amd64'
uses: docker/setup-qemu-action@v3
with:
platforms: amd64
- name: Install Rust and musl-tools
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain*') }}
- name: Install musl tools
run: |
sudo apt-get update
sudo apt-get install -y musl-tools
if [ "${{ matrix.arch }}" = "amd64" ]; then
sudo apt-get install -y gcc-multilib
fi
- name: Build static binary
run: cargo build --release --target ${{ matrix.target }}
- name: Create Alpine package structure
run: |
mkdir -p apk-build/bin
cp target/${{ matrix.target }}/release/rco apk-build/bin/
- name: Upload Linux musl binary
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.target }}
path: target/${{ matrix.target }}/release/rco
retention-days: 5
- name: Create APKBUILD
run: |
VERSION="${{ github.event.inputs.version || github.ref_name }}"
VERSION="${VERSION#v}"
cat > apk-build/APKBUILD << 'EOF'
# Contributor: Rusty Commit <rusty-commit@users.noreply.github.com>
# Maintainer: Rusty Commit <rusty-commit@users.noreply.github.com>
pkgname=rusty-commit
pkgver=VERSION_PLACEHOLDER
pkgrel=0
pkgdesc="A modern, AI-powered git commit message generator"
url="https://github.com/hongkongkiwi/rusty-commit"
arch="${{ matrix.apk_arch }}"
license="MIT"
depends=""
subpackages=""
source=""
options="!check"
build() {
return 0
}
package() {
mkdir -p "$pkgdir"/usr/bin
install -m 755 "$startdir"/bin/rco "$pkgdir"/usr/bin/rco
}
EOF
sed -i "s/VERSION_PLACEHOLDER/${VERSION}/" apk-build/APKBUILD
- name: Build .apk package
run: |
mkdir -p apk-packages
docker run --rm \
-v "$PWD:/work" \
-w /work/apk-build \
alpine:3.19 \
sh -c 'apk add --no-cache alpine-sdk && \
adduser -D builder && addgroup builder abuild && \
chown -R builder:builder /work/apk-build /work/apk-packages && \
su builder -c "export REPODEST=/work/apk-packages PACKAGER= && abuild-keygen -a -n" && \
cp /home/builder/.abuild/*.rsa.pub /etc/apk/keys/ && \
su builder -c "export REPODEST=/work/apk-packages PACKAGER= && abuild -r"'
- name: Upload Alpine package
uses: actions/upload-artifact@v4
with:
name: rusty-commit.apk-${{ matrix.arch }}
path: apk-packages/**/*.apk
finalize-release:
name: Finalize Release
needs:
- release
- build-deb
- build-rpm
- build-apk
- publish-docker
runs-on: ubuntu-latest
steps:
- name: Download release assets
uses: actions/download-artifact@v4
with:
name: release
path: release-assets
- name: List downloaded assets
run: |
echo "=== release-assets contents ==="
find release-assets -type f -exec ls -la {} \;
- name: Download all packages
uses: actions/download-artifact@v4
with:
path: packages
pattern: rusty-commit.*
merge-multiple: false
- name: Prepare release assets
run: |
mkdir -p release-packages
# Copy release assets
cp -r release-assets/* release-packages/ 2>/dev/null || true
# Copy platform packages
for dir in packages/*; do
if [ -d "$dir" ]; then
cp -r "$dir"/* release-packages/ 2>/dev/null || true
fi
done
ls -la release-packages/
- name: Generate SHA256 checksums
run: |
cd release-packages
find . -maxdepth 1 -type f -exec sha256sum {} \; > SHA256SUMS.txt
cat SHA256SUMS.txt
- name: Setup GPG for signing
if: env.GPG_PRIVATE_KEY != ''
uses: actions/cache@v4
with:
path: ~/.gnupg
key: gpg-key-${{ env.GPG_PRIVATE_KEY }}
- name: Import GPG key
if: env.GPG_PRIVATE_KEY != ''
run: |
echo '${{ env.GPG_PRIVATE_KEY }}' | gpg --batch --import --
gpg --list-secret-keys --keyid-format LONG
- name: Sign checksums
if: env.GPG_PRIVATE_KEY != ''
run: |
cd release-packages
gpg --batch --yes --armor --detach-sign SHA256SUMS.txt
cat SHA256SUMS.txt.asc
- name: Upload SHA256 checksums
uses: actions/upload-artifact@v4
with:
name: sha256sums
path: release-packages/SHA256SUMS.txt
retention-days: 5
- name: Upload GPG signature
if: env.GPG_PRIVATE_KEY != ''
uses: actions/upload-artifact@v4
with:
name: sha256sums-asc
path: release-packages/SHA256SUMS.txt.asc
retention-days: 5
- name: Update GitHub Release
uses: softprops/action-gh-release@v2.5.0
with:
draft: false
prerelease: false
files: release-packages/*
publish-docker:
name: Publish Docker Image (Multi-Arch)
needs:
- build-apk
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download Linux musl binaries (amd64)
uses: actions/download-artifact@v4
with:
name: binary-x86_64-unknown-linux-musl
path: docker-bin/amd64
- name: Download Linux musl binaries (arm64)
uses: actions/download-artifact@v4
with:
name: binary-aarch64-unknown-linux-musl
path: docker-bin/arm64
- name: Prepare Docker binaries
run: |
mkdir -p docker-bin
mv docker-bin/amd64/rco docker-bin/rusty-commit-amd64
mv docker-bin/arm64/rco docker-bin/rusty-commit-arm64
chmod +x docker-bin/rusty-commit-amd64 docker-bin/rusty-commit-arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up QEMU for multi-arch builds
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push multi-architecture Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
update-homebrew:
name: Update Homebrew Formula
needs: finalize-release
runs-on: ubuntu-latest
steps:
- name: Checkout homebrew-rusty-commit
uses: actions/checkout@v4
with:
repository: hongkongkiwi/homebrew-rusty-commit
token: ${{ secrets.HOMEBREW_REPO_UPDATE_TOKEN }}
path: homebrew-tap
- name: Download SHA256 checksums
uses: actions/download-artifact@v4
with:
name: sha256sums
path: homebrew-tmp
- name: Extract SHA256 checksums for all platforms
id: sha256
run: |
# Extract SHA256 for each platform (files include version prefix like v1.0.18)
# Note: releases use musl for Linux, not gnu
SHA256_X86_64_DARWIN=$(grep -E 'rusty-commit-.*-x86_64-apple-darwin\.tar\.gz' homebrew-tmp/SHA256SUMS.txt | awk '{print $1}')
SHA256_AARCH64_DARWIN=$(grep -E 'rusty-commit-.*-aarch64-apple-darwin\.tar\.gz' homebrew-tmp/SHA256SUMS.txt | awk '{print $1}')
SHA256_X86_64_LINUX=$(grep -E 'rusty-commit-.*-x86_64-unknown-linux-musl\.tar\.gz' homebrew-tmp/SHA256SUMS.txt | awk '{print $1}')
SHA256_AARCH64_LINUX=$(grep -E 'rusty-commit-.*-aarch64-unknown-linux-musl\.tar\.gz' homebrew-tmp/SHA256SUMS.txt | awk '{print $1}')
for value in "$SHA256_X86_64_DARWIN" "$SHA256_AARCH64_DARWIN" "$SHA256_X86_64_LINUX" "$SHA256_AARCH64_LINUX"; do
if [ -z "$value" ]; then
echo "Missing SHA256 checksum for one or more platforms" >&2
exit 1
fi
done
{
echo "sha256_x86_64_darwin=${SHA256_X86_64_DARWIN}"
echo "sha256_aarch64_darwin=${SHA256_AARCH64_DARWIN}"
echo "sha256_x86_64_linux=${SHA256_X86_64_LINUX}"
echo "sha256_aarch64_linux=${SHA256_AARCH64_LINUX}"
} >> "$GITHUB_OUTPUT"
echo "SHA256 x86_64-darwin: $SHA256_X86_64_DARWIN"
echo "SHA256 aarch64-darwin: $SHA256_AARCH64_DARWIN"
echo "SHA256 x86_64-linux-musl: $SHA256_X86_64_LINUX"
echo "SHA256 aarch64-linux-musl: $SHA256_AARCH64_LINUX"
- name: Update Homebrew formula
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
SHA256_X86_64_DARWIN="${{ steps.sha256.outputs.sha256_x86_64_darwin }}"
SHA256_AARCH64_DARWIN="${{ steps.sha256.outputs.sha256_aarch64_darwin }}"
SHA256_X86_64_LINUX="${{ steps.sha256.outputs.sha256_x86_64_linux }}"
SHA256_AARCH64_LINUX="${{ steps.sha256.outputs.sha256_aarch64_linux }}"
cat > homebrew-tap/Formula/rusty-commit.rb << EOF
class RustyCommit < Formula
desc "Rust-powered AI commit message generator with 18+ AI providers"
homepage "https://github.com/hongkongkiwi/rusty-commit"
license "MIT"
version "${VERSION}"
on_macos do
on_arm do
url "https://github.com/hongkongkiwi/rusty-commit/releases/download/v${VERSION}/rusty-commit-v${VERSION}-aarch64-apple-darwin.tar.gz"
sha256 "${SHA256_AARCH64_DARWIN}"
end
on_intel do
url "https://github.com/hongkongkiwi/rusty-commit/releases/download/v${VERSION}/rusty-commit-v${VERSION}-x86_64-apple-darwin.tar.gz"
sha256 "${SHA256_X86_64_DARWIN}"
end
end
on_linux do
on_arm do
url "https://github.com/hongkongkiwi/rusty-commit/releases/download/v${VERSION}/rusty-commit-v${VERSION}-aarch64-unknown-linux-musl.tar.gz"
sha256 "${SHA256_AARCH64_LINUX}"
end
on_x86_64 do
url "https://github.com/hongkongkiwi/rusty-commit/releases/download/v${VERSION}/rusty-commit-v${VERSION}-x86_64-unknown-linux-musl.tar.gz"
sha256 "${SHA256_X86_64_LINUX}"
end
end
def install
bin.install "rco"
end
test do
assert_match version.to_s, shell_output("#{bin}/rco --version").strip
end
end
EOF
cat homebrew-tap/Formula/rusty-commit.rb
- name: Commit and push changes
working-directory: ./homebrew-tap
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/rusty-commit.rb README.md
git commit -m "Update rusty-commit to v${VERSION}"
git push
update-precommit:
name: Update Pre-commit Hook
needs: finalize-release
runs-on: ubuntu-latest
steps:
- name: Checkout precommit-rusty-commit
uses: actions/checkout@v4
with:
repository: hongkongkiwi/precommit-rusty-commit
token: ${{ secrets.PRECOMMIT_REPO_UPDATE_TOKEN }}
path: precommit-tap
- name: Update pre-commit hooks version
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
# Update the rev in .pre-commit-hooks.yaml
sed -i "s/rev: v[0-9]\+\.[0-9]\+\.[0-9]\+/rev: v${VERSION}/" precommit-tap/.pre-commit-hooks.yaml
# Update version references in README.md
sed -i "s/rusty-commit v[0-9]\+\.[0-9]\+\.[0-9]\+/rusty-commit v${VERSION}/g" precommit-tap/README.md
sed -i "s/v[0-9]\+\.[0-9]\+\.[0-9]\]*/v${VERSION}/g" precommit-tap/README.md
cat precommit-tap/.pre-commit-hooks.yaml
- name: Commit and push changes
working-directory: ./precommit-tap
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .pre-commit-hooks.yaml README.md
git commit -m "Update rusty-commit to v${VERSION}"
git push
update-actions:
name: Update GitHub Action
needs: finalize-release
runs-on: ubuntu-latest
steps:
- name: Checkout action-rusty-commit
uses: actions/checkout@v4
with:
repository: hongkongkiwi/action-rusty-commit
token: ${{ secrets.ACTIONS_REPO_UPDATE_TOKEN }}
path: actions-tap
- name: Update action version
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
# Update the version in action.yml (if it has a tag reference)
sed -i "s/tag: v[0-9]\+\.[0-9]\+\.[0-9]\+/tag: v${VERSION}/" actions-tap/action.yml 2>/dev/null || true
cat actions-tap/action.yml
- name: Commit and push changes
working-directory: ./actions-tap
run: |
VERSION_RAW='${{ github.event.inputs.version || github.ref_name }}'
VERSION="${VERSION_RAW#v}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add action.yml README.md 2>/dev/null || git add action.yml
git commit -m "Update rusty-commit to v${VERSION}"
git push