Skip to content

Build git-filter-repo Binaries #9

Build git-filter-repo Binaries

Build git-filter-repo Binaries #9

# Copyright (c) 2026 Gili Tzabari. All rights reserved.
#
# Licensed under the CAT Commercial License.
# See LICENSE.md in the project root for license terms.
name: Build git-filter-repo Binaries
on:
workflow_dispatch:
inputs:
version:
description: 'git-filter-repo version tag (e.g., v2.38.0)'
required: true
default: 'v2.38.0'
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux-x64
- os: ubuntu-24.04-arm
platform: linux-aarch64
- os: macos-26-intel
platform: macos-x64
- os: macos-latest
platform: macos-aarch64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Validate version input
run: |
set -euo pipefail
VERSION="${{ github.event.inputs.version }}"
if ! echo "${VERSION}" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: Version '${VERSION}' does not match required format vX.Y.Z (e.g., v2.38.0)." >&2
exit 1
fi
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install PyInstaller
run: pip install pyinstaller
- name: Download git-filter-repo
run: |
set -euo pipefail
VERSION="${{ github.event.inputs.version }}"
curl -fsSL -o git-filter-repo.py \
"https://raw.githubusercontent.com/newren/git-filter-repo/${VERSION}/git-filter-repo"
- name: Build standalone binary with PyInstaller
run: |
set -euo pipefail
pyinstaller \
--onefile \
--name git-filter-repo \
--add-data "git-filter-repo.py:." \
git-filter-repo.py
ls -lh dist/git-filter-repo
- name: Verify binary runs
run: |
set -euo pipefail
./dist/git-filter-repo --version
- name: Generate SHA256 checksum
run: |
set -euo pipefail
cd dist
sha256sum git-filter-repo > git-filter-repo-${{ matrix.platform }}.sha256
cat git-filter-repo-${{ matrix.platform }}.sha256
- name: Rename binary for platform
run: |
set -euo pipefail
mv dist/git-filter-repo dist/git-filter-repo-${{ matrix.platform }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: git-filter-repo-${{ matrix.platform }}
path: |
dist/git-filter-repo-${{ matrix.platform }}
dist/git-filter-repo-${{ matrix.platform }}.sha256
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Verify all expected artifacts are present
run: |
set -euo pipefail
EXPECTED=(
git-filter-repo-linux-x64
git-filter-repo-linux-aarch64
git-filter-repo-macos-x64
git-filter-repo-macos-aarch64
git-filter-repo-linux-x64.sha256
git-filter-repo-linux-aarch64.sha256
git-filter-repo-macos-x64.sha256
git-filter-repo-macos-aarch64.sha256
)
MISSING=()
for FILE in "${EXPECTED[@]}"; do
if [[ ! -f "artifacts/${FILE}" ]]; then
MISSING+=("${FILE}")
fi
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "ERROR: Missing required artifact files before release creation:" >&2
for FILE in "${MISSING[@]}"; do
echo " - ${FILE}" >&2
done
echo "All 4 platform builds must succeed before a release can be created." >&2
exit 1
fi
- name: Read SHA256 checksums
id: checksums
run: |
set -euo pipefail
LINUX_X64=$(awk '{print $1}' artifacts/git-filter-repo-linux-x64.sha256)
LINUX_AARCH64=$(awk '{print $1}' artifacts/git-filter-repo-linux-aarch64.sha256)
MACOS_X64=$(awk '{print $1}' artifacts/git-filter-repo-macos-x64.sha256)
MACOS_AARCH64=$(awk '{print $1}' artifacts/git-filter-repo-macos-aarch64.sha256)
echo "linux_x64=${LINUX_X64}" >> $GITHUB_OUTPUT
echo "linux_aarch64=${LINUX_AARCH64}" >> $GITHUB_OUTPUT
echo "macos_x64=${MACOS_X64}" >> $GITHUB_OUTPUT
echo "macos_aarch64=${MACOS_AARCH64}" >> $GITHUB_OUTPUT
# The SHA256 checksums written into this release are consumed by
# plugin/scripts/download-git-filter-repo.sh (implemented in issue
# 2.1-replace-bfg-with-git-filter-repo) and stored in
# plugin/.git-filter-repo-config/release.conf.
- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: git-filter-repo-${{ github.event.inputs.version }}
name: git-filter-repo ${{ github.event.inputs.version }} Standalone Binaries
body: |
## git-filter-repo ${{ github.event.inputs.version }} Standalone Binaries
Pre-built standalone binaries of [git-filter-repo](https://github.com/newren/git-filter-repo)
compiled with PyInstaller. No Python installation required.
### Platforms
| Platform | File | SHA256 |
|----------|------|--------|
| Linux x86_64 | `git-filter-repo-linux-x64` | `${{ steps.checksums.outputs.linux_x64 }}` |
| Linux ARM64 | `git-filter-repo-linux-aarch64` | `${{ steps.checksums.outputs.linux_aarch64 }}` |
| macOS Intel | `git-filter-repo-macos-x64` | `${{ steps.checksums.outputs.macos_x64 }}` |
| macOS Apple Silicon | `git-filter-repo-macos-aarch64` | `${{ steps.checksums.outputs.macos_aarch64 }}` |
### Usage
The CAT plugin automatically downloads the appropriate binary on first use.
Set `GFR_FORCE_DOWNLOAD=1` to force re-download and re-verification.
files: |
artifacts/git-filter-repo-linux-x64
artifacts/git-filter-repo-linux-aarch64
artifacts/git-filter-repo-macos-x64
artifacts/git-filter-repo-macos-aarch64
artifacts/git-filter-repo-linux-x64.sha256
artifacts/git-filter-repo-linux-aarch64.sha256
artifacts/git-filter-repo-macos-x64.sha256
artifacts/git-filter-repo-macos-aarch64.sha256
draft: false
prerelease: false