Modify build workflow to automate api changes #45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and Release | |
on: | |
push: | |
branches: [ "master" ] | |
pull_request: | |
branches: [ "master" ] | |
workflow_dispatch: | |
inputs: | |
create_release: | |
description: 'Create a new release' | |
required: false | |
type: boolean | |
default: false | |
schedule: | |
- cron: '0 2 * * *' | |
env: | |
BUILD_TYPE: Release | |
MIN_BUILD_NUMBER: 7290 | |
jobs: | |
check-versions: | |
runs-on: ubuntu-latest | |
outputs: | |
should_build: ${{ steps.check.outputs.should_build }} | |
versions_matrix: ${{ steps.check.outputs.versions_matrix }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
fetch-depth: 0 | |
- name: Check for new versions | |
id: check | |
run: | | |
cd binaryninjaapi | |
git fetch --tags origin | |
VERSIONS_JSON='[{"name": "dev", "filename": "dev", "short_name": "dev", "full_version": "dev"}]' | |
ALL_TAGS=$(git tag -l 'v*-stable' 'stable/*' | sort -V) | |
for tag in $ALL_TAGS; do | |
if [[ $tag == v*-stable ]]; then | |
VERSION=$(echo $tag | sed 's/^v//' | sed 's/-stable$//') | |
elif [[ $tag == stable/* ]]; then | |
VERSION=$(echo $tag | sed 's|stable/||') | |
else | |
continue | |
fi | |
BUILD_NUM=$(echo $VERSION | grep -oE '[0-9]{4}$') | |
if [[ ! -z "$BUILD_NUM" ]] && [[ $BUILD_NUM -ge $MIN_BUILD_NUMBER ]]; then | |
echo "Including version: $tag (build $BUILD_NUM)" | |
VERSIONS_JSON=$(echo $VERSIONS_JSON | jq -c --arg name "$tag" --arg filename "v$VERSION-stable" --arg short "$BUILD_NUM" --arg fullver "$VERSION" '. += [{"name": $name, "filename": $filename, "short_name": $short, "full_version": $fullver}]') | |
fi | |
done | |
echo "versions_matrix<<EOF" >> $GITHUB_OUTPUT | |
echo "$VERSIONS_JSON" >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
if [[ "${{ github.event_name }}" == "schedule" ]] || [[ "${{ inputs.create_release }}" == "true" ]]; then | |
echo "should_build=true" >> $GITHUB_OUTPUT | |
else | |
echo "should_build=false" >> $GITHUB_OUTPUT | |
fi | |
build: | |
needs: check-versions | |
if: needs.check-versions.outputs.should_build == 'true' || github.event_name == 'push' || github.event_name == 'pull_request' | |
runs-on: ${{ matrix.config.os }} | |
strategy: | |
matrix: | |
config: | |
- { os: windows-latest, name: windows, ext: dll } | |
- { os: macos-15, name: macos, ext: dylib } | |
- { os: ubuntu-24.04, name: ubuntu, ext: so } | |
version: ${{ fromJson(needs.check-versions.outputs.versions_matrix) }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
- uses: seanmiddleditch/gha-setup-ninja@master | |
- uses: ilammy/msvc-dev-cmd@v1 | |
if: matrix.config.name == 'windows' | |
- name: Setup Python | |
uses: actions/setup-python@v6 | |
with: | |
python-version: '3.13' | |
- name: Update submodule | |
run: | | |
cd binaryninjaapi | |
git fetch --tags | |
git checkout --force ${{ matrix.version.name }} | |
git submodule update --init --recursive | |
- name: Configure CMake | |
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBN_ALLOW_STUBS=ON | |
- name: Build | |
run: cmake --build build --config ${{env.BUILD_TYPE}} | |
- name: Rename artifacts (Windows) | |
if: matrix.config.name == 'windows' | |
shell: pwsh | |
run: | | |
cd build | |
$original = Get-ChildItem -Recurse -Filter "*NativePredicateSolver*.dll" | Select-Object -First 1 | |
if ($null -eq $original) { | |
Write-Error "Built library not found" | |
exit 1 | |
} | |
if ("${{ matrix.version.full_version }}" -eq "dev") { | |
$newName = "NativePredicateSolver-dev.dll" | |
} else { | |
$newName = "NativePredicateSolver-${{ matrix.version.full_version }}.dll" | |
} | |
Copy-Item -Path $original.FullName -Destination $newName | |
echo "artifact_name=$newName" >> $env:GITHUB_ENV | |
- name: Rename artifacts (Unix) | |
if: matrix.config.name != 'windows' | |
shell: bash | |
run: | | |
cd build | |
if [[ "${{ matrix.config.ext }}" == "so" ]]; then | |
ORIGINAL=$(find . -type f -name "libNativePredicateSolver.so*" | head -n 1) | |
else | |
ORIGINAL=$(find . -type f -name "libNativePredicateSolver.dylib*" | head -n 1) | |
fi | |
if [[ -z "$ORIGINAL" ]]; then | |
echo "Built library not found" | |
exit 1 | |
fi | |
if [[ "${{ matrix.version.full_version }}" == "dev" ]]; then | |
NEW_NAME="NativePredicateSolver-dev.${{ matrix.config.ext }}" | |
else | |
NEW_NAME="NativePredicateSolver-${{ matrix.version.full_version }}.${{ matrix.config.ext }}" | |
fi | |
cp "$ORIGINAL" "$NEW_NAME" | |
echo "artifact_name=$NEW_NAME" >> $GITHUB_ENV | |
- name: Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.config.name }}-${{ matrix.version.filename }} | |
path: build/${{ env.artifact_name }} | |
create-release: | |
needs: [check-versions, build] | |
if: needs.check-versions.outputs.should_build == 'true' || github.event.inputs.create_release == 'true' || github.event_name == 'push' | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Download all artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: artifacts | |
- name: Organize artifacts | |
run: | | |
mkdir -p release_files | |
find artifacts -type f \( -name "*.dll" -o -name "*.so" -o -name "*.dylib" \) -exec cp {} release_files/ \; | |
- name: Generate release notes | |
run: | | |
RELEASE_DATE=$(date +'%Y-%m-%d') | |
cat > release_notes.md <<EOF | |
## Build Information | |
**Date:** ${RELEASE_DATE} | |
**Commit:** \`${GITHUB_SHA:0:7}\` | |
### Supported Binary Ninja Versions | |
EOF | |
echo '${{ needs.check-versions.outputs.versions_matrix }}' > versions.json | |
jq -r '.[] | "- \(.full_version) (build \(.short_name))"' versions.json >> release_notes.md | |
cat >> release_notes.md <<EOF | |
### Installation | |
**Option 1 (Recommended):** Use the [loader plugin](https://github.com/ScriptWare-Software/native-predicate-solver_loader) which automatically downloads and updates the correct binary for your Binary Ninja version. | |
**Option 2:** Manual installation - download the appropriate binary for your platform and Binary Ninja version, then place it in your Binary Ninja plugins directory. | |
**Naming format:** | |
- Stable: \`NativePredicateSolver-<version>.<ext>\` | |
- Dev: \`NativePredicateSolver-dev.<ext>\` | |
Where \`<ext>\` is \`dll\` (Windows), \`so\` (Linux), or \`dylib\` (macOS). | |
EOF | |
- name: Create Release | |
uses: softprops/action-gh-release@v1 | |
with: | |
tag_name: build-${{ github.run_number }} | |
name: Build ${{ github.run_number }} | |
body_path: release_notes.md | |
files: release_files/* | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |