Skip to content

Automated Git Bisect #34

Automated Git Bisect

Automated Git Bisect #34

name: Automated Git Bisect
on:
workflow_dispatch:
inputs:
org_repo:
description: 'Organization and repository name (e.g., org/repo)'
default: "SweetRainGarden/SrgGitRecordsRepo"
required: true
check_commands:
description: 'Commands to test each commit, separated by "&&"'
default: ./gradlew clean && ./gradlew test
required: true
init_branch_name:
description: 'Initial branch name to start the bisect process'
default: "develop"
required: true
good_commit:
description: 'Known good commit'
default: "c7e772928a6b222f1b34126cf1e586ffa98a923e"
required: true
bad_commit:
description: 'Known bad commit (optional, defaults to the latest commit of the initial branch)'
default: "3a97867dcfd0f0e74980f25e6fbc1c41a5c9075a"
required: false
java_version:
description: 'Java version to use for the build'
required: false
default: '17'
gh_token:
description: 'GitHub Token for cloning and accessing the repository if it is for an private repository'
required: false
jobs:
job_bisect:
runs-on: [ 'macos-latest' ]
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.1
with:
repository: ${{ github.event.inputs.org_repo }}
token: ${{ secrets.GITHUB_TOKEN || github.event.inputs.gh_token }}
ref: ${{ github.event.inputs.init_branch_name }}
fetch-depth: '0'
- name: "EEE -> Set build env --> 1: JDK 17"
uses: actions/setup-java@v4.2.1
with:
java-version: '${{ github.event.inputs.java_version }}'
distribution: 'temurin'
- name: "EEE -> Set build env --> 2: Gradle current stable version"
uses: gradle/gradle-build-action@v3.1.0
with:
gradle-version: current
- name: Set up Android SDK
uses: android-actions/setup-android@v3.2.0
- name: Resolve bad commit
run: |
if [[ -z "${{ github.event.inputs.bad_commit }}" ]]; then
INIT_BAD_COMMIT_ID=$(git rev-parse HEAD)
elif git rev-parse --verify --quiet ${{ github.event.inputs.bad_commit }}^{commit}; then
INIT_BAD_COMMIT_ID=${{ github.event.inputs.bad_commit }}
else
echo "The specified bad commit is invalid."
exit 1
fi
echo "INIT_BAD_COMMIT_ID=$INIT_BAD_COMMIT_ID" >> $GITHUB_ENV
- name: Create the check script
run: |
# Trim leading and trailing '&&' and replace with a single newline character
COMMANDS="${{ github.event.inputs.check_commands }}"
COMMANDS="${COMMANDS##&&}" # Remove leading &&
COMMANDS="${COMMANDS%%&&}" # Remove trailing &&
# Split commands by '&&' and write to a script file
IFS='&&' read -ra CMD_ARRAY <<< "$COMMANDS"
for CMD in "${CMD_ARRAY[@]}"; do
# Trim any leading and trailing whitespace from each command
CMD="$(echo "$CMD" | xargs)"
# Skip empty commands
if [ -n "$CMD" ]; then
echo "$CMD" >> bisect_check.sh
fi
done
chmod +x bisect_check.sh
- name: Check the good commit
run: |
if git checkout ${{ github.event.inputs.good_commit }}; then
echo "The specified good commit:${{ github.event.inputs.good_commit }} is valid in git history" >> $GITHUB_STEP_SUMMARY
# Run bisect check bash here, if it is not valid, exit 1 and print the error message
if ! ./bisect_check.sh; then
echo "The specified good commit:${{ github.event.inputs.good_commit }} is invalid in the check command, which means the input good commit is actually not good for your check command." >> $GITHUB_STEP_SUMMARY
git checkout -
exit 1
else
echo "The specified good commit:${{ github.event.inputs.good_commit }} is valid in the check command." >> $GITHUB_STEP_SUMMARY
git checkout -
fi
else
echo "The specified good commit:${{ github.event.inputs.good_commit }} is invalid in git history" >> $GITHUB_STEP_SUMMARY
exit 1
fi
- name: Run bisect with check command bash
run: |
git bisect start
git bisect bad $INIT_BAD_COMMIT_ID
git bisect good ${{ github.event.inputs.good_commit }}
BISECT_OUTPUT=$(git bisect run ./bisect_check.sh)
echo "$BISECT_OUTPUT"
FIRST_BAD_COMMIT=$(git rev-parse bisect/bad)
echo "##Bisect log:" >> $GITHUB_STEP_SUMMARY
git bisect log >> temp.txt
cat temp.txt >> $GITHUB_STEP_SUMMARY
git bisect reset
echo "## Bisect result" >> $GITHUB_STEP_SUMMARY
if [[ -z "$FIRST_BAD_COMMIT" ]]; then
echo "No bad commit found."
echo "No bad commit found." >> $GITHUB_STEP_SUMMARY
else
DIFF_URL="https://github.com/${{ github.event.inputs.org_repo }}/commit/${FIRST_BAD_COMMIT}"
echo "FIRST_BAD_COMMIT=$FIRST_BAD_COMMIT" >> $GITHUB_ENV
echo "FIRST_BAD_COMMIT: [$FIRST_BAD_COMMIT]($DIFF_URL)" >> $GITHUB_STEP_SUMMARY
ERROR_LOG=$(echo "$BISECT_OUTPUT" | awk '/first bad commit: first commit that fails/{flag=1; next} /Bisecting:/{flag=0} flag')
echo "### Error log:" >> $GITHUB_STEP_SUMMARY
echo "$ERROR_LOG" >> $GITHUB_STEP_SUMMARY
fi