1- name : Build 
1+ name : Build and Release  
22
33on :
44 push :
55 branches : [ "master" ] 
66 pull_request :
77 branches : [ "master" ] 
8+  workflow_dispatch :
9+  inputs :
10+  create_release :
11+  description : ' Create a new release' 
12+  required : false 
13+  type : boolean 
14+  default : false 
15+  schedule :
16+  - cron : ' 0 2 * * *' 
817
918env :
10-  BUILD_TYPE : RelWithDebInfo 
19+  BUILD_TYPE : Release 
20+  MIN_BUILD_NUMBER : 7290 
1121
1222jobs :
23+  check-versions :
24+  runs-on : ubuntu-latest 
25+  outputs :
26+  should_build : ${{ steps.check.outputs.should_build }} 
27+  versions_matrix : ${{ steps.check.outputs.versions_matrix }} 
28+  steps :
29+  - uses : actions/checkout@v4 
30+  with :
31+  submodules : ' true' 
32+  fetch-depth : 0 
33+  
34+  - name : Check for new versions 
35+  id : check 
36+  run : | 
37+  cd binaryninjaapi 
38+  git fetch --tags origin 
39+   
40+  VERSIONS_JSON='[{"name": "dev", "filename": "dev", "short_name": "dev", "full_version": "dev"}]' 
41+   
42+  ALL_TAGS=$(git tag -l 'v*-stable' 'stable/*' | sort -V) 
43+   
44+  for tag in $ALL_TAGS; do 
45+  if [[ $tag == v*-stable ]]; then 
46+  VERSION=$(echo $tag | sed 's/^v//' | sed 's/-stable$//') 
47+  elif [[ $tag == stable/* ]]; then 
48+  VERSION=$(echo $tag | sed 's|stable/||') 
49+  else 
50+  continue 
51+  fi 
52+   
53+  BUILD_NUM=$(echo $VERSION | grep -oE '[0-9]{4}$') 
54+   
55+  if [[ ! -z "$BUILD_NUM" ]] && [[ $BUILD_NUM -ge $MIN_BUILD_NUMBER ]]; then 
56+  echo "Including version: $tag (build $BUILD_NUM)" 
57+  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}]') 
58+  fi 
59+  done 
60+   
61+  echo "versions_matrix<<EOF" >> $GITHUB_OUTPUT 
62+  echo "$VERSIONS_JSON" >> $GITHUB_OUTPUT 
63+  echo "EOF" >> $GITHUB_OUTPUT 
64+   
65+  if [[ "${{ github.event_name }}" == "schedule" ]] || [[ "${{ inputs.create_release }}" == "true" ]]; then 
66+  echo "should_build=true" >> $GITHUB_OUTPUT 
67+  else 
68+  echo "should_build=false" >> $GITHUB_OUTPUT 
69+  fi 
70+ 
1371build :
14-  runs-on : ${{matrix.config.os}} 
72+  needs : check-versions 
73+  if : needs.check-versions.outputs.should_build == 'true' || github.event_name == 'push' || github.event_name == 'pull_request' 
74+  runs-on : ${{ matrix.config.os }} 
1575 strategy :
1676 matrix :
1777 config :
18-  - { 
19-  os : windows-2025, 
20-  name : windows 
21-  } 
22-  - { 
23-  os : macos-13, 
24-  name : macos 
25-  } 
26-  - { 
27-  os : ubuntu-24.04, 
28-  name : ubuntu 
29-  } 
30-  version :
31-  - name : v5.0.7290-stable 
32-  use-patch : false 
33-  - name : v5.0.7648-stable 
34-  use-patch : false 
35-  - name : dev 
36-  use-patch : false 
78+  - { os: windows-latest, name: windows, ext: dll } 
79+  - { os: macos-15, name: macos, ext: dylib } 
80+  - { os: ubuntu-24.04, name: ubuntu, ext: so } 
81+  version : ${{ fromJson(needs.check-versions.outputs.versions_matrix) }} 
82+  
3783 steps :
38-  - uses : actions/checkout@v3  
84+  - uses : actions/checkout@v4  
3985 with :
4086 submodules : ' true' 
87+  
4188 - uses : seanmiddleditch/gha-setup-ninja@master 
89+ 
4290 - uses : ilammy/msvc-dev-cmd@v1 
91+  if : matrix.config.name == 'windows' 
92+  
93+  - name : Setup Python 
94+  uses : actions/setup-python@v6 
95+  with :
96+  python-version : ' 3.13' 
97+ 
4398 - name : Update submodule 
4499 run : | 
45100 cd binaryninjaapi 
46101 git fetch --tags 
47-  git checkout --force ${{matrix.version.name}} 
102+  git checkout --force ${{  matrix.version.name  }} 
48103 git submodule update --init --recursive 
49- name : Patch api to allow building headlessly 
50-  if : ${{ matrix.version.use-patch }} 
51-  shell : bash 
52-  run : | 
53-  cd binaryninjaapi 
54-  git apply --verbose ${{matrix.version.patch-file}}  
104+ 
55105name : Configure CMake 
56-  run : cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 
106+  run : cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBN_ALLOW_STUBS=ON 
107+  
57108 - name : Build 
58-  run : cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 
109+  run : cmake --build build --config ${{env.BUILD_TYPE}} 
110+  
111+  - name : Rename artifacts (Windows) 
112+  if : matrix.config.name == 'windows' 
113+  shell : pwsh 
114+  run : | 
115+  cd build 
116+  $original = Get-ChildItem -Recurse -Filter "*NativePredicateSolver*.dll" | Select-Object -First 1 
117+   
118+  if ($null -eq $original) { 
119+  Write-Error "Built library not found" 
120+  exit 1 
121+  } 
122+   
123+  if ("${{ matrix.version.full_version }}" -eq "dev") { 
124+  $newName = "NativePredicateSolver-dev.dll" 
125+  } else { 
126+  $newName = "NativePredicateSolver-${{ matrix.version.full_version }}.dll" 
127+  } 
128+   
129+  Copy-Item -Path $original.FullName -Destination $newName 
130+  echo "artifact_name=$newName" >> $env:GITHUB_ENV 
131+ 
132+  - name : Rename artifacts (Unix) 
133+  if : matrix.config.name != 'windows' 
134+  shell : bash 
135+  run : | 
136+  cd build 
137+   
138+  if [[ "${{ matrix.config.ext }}" == "so" ]]; then 
139+  ORIGINAL=$(find . -type f -name "libNativePredicateSolver.so*" | head -n 1) 
140+  else 
141+  ORIGINAL=$(find . -type f -name "libNativePredicateSolver.dylib*" | head -n 1) 
142+  fi 
143+   
144+  if [[ -z "$ORIGINAL" ]]; then 
145+  echo "Built library not found" 
146+  exit 1 
147+  fi 
148+   
149+  if [[ "${{ matrix.version.full_version }}" == "dev" ]]; then 
150+  NEW_NAME="NativePredicateSolver-dev.${{ matrix.config.ext }}" 
151+  else 
152+  NEW_NAME="NativePredicateSolver-${{ matrix.version.full_version }}.${{ matrix.config.ext }}" 
153+  fi 
154+   
155+  cp "$ORIGINAL" "$NEW_NAME" 
156+  echo "artifact_name=$NEW_NAME" >> $GITHUB_ENV 
157+ 
59158 - name : Upload artifact 
60159 uses : actions/upload-artifact@v4 
61160 with :
62-  name : ${{matrix.config.name}}-${{matrix.version.name}} 
63-  path : ${{github.workspace}}/build/*NativePredicateSolver* 
161+  name : ${{ matrix.config.name }}-${{ matrix.version.filename }} 
162+  path : build/${{ env.artifact_name }} 
163+ 
164+  create-release :
165+  needs : [check-versions, build] 
166+  if : needs.check-versions.outputs.should_build == 'true' || github.event.inputs.create_release == 'true' || github.event_name == 'push' 
167+  runs-on : ubuntu-latest 
168+  permissions :
169+  contents : write 
170+  
171+  steps :
172+  - uses : actions/checkout@v4 
173+  
174+  - name : Download all artifacts 
175+  uses : actions/download-artifact@v4 
176+  with :
177+  path : artifacts 
178+  
179+  - name : Organize artifacts 
180+  run : | 
181+  mkdir -p release_files 
182+  find artifacts -type f \( -name "*.dll" -o -name "*.so" -o -name "*.dylib" \) -exec cp {} release_files/ \; 
183+ 
184+  - name : Generate release notes 
185+  run : | 
186+  RELEASE_DATE=$(date +'%Y-%m-%d') 
187+   
188+  cat > release_notes.md <<EOF 
189+  ## Build Information 
190+ 
191+  **Date:** ${RELEASE_DATE} 
192+  **Commit:** \`${GITHUB_SHA:0:7}\` 
193+ 
194+  ### Supported Binary Ninja Versions 
195+ 
196+  EOF 
197+   
198+  echo '${{ needs.check-versions.outputs.versions_matrix }}' > versions.json 
199+  jq -r '.[] | "- \(.full_version) (build \(.short_name))"' versions.json >> release_notes.md 
200+   
201+  cat >> release_notes.md <<EOF 
202+ 
203+  ### Installation 
204+ 
205+  **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. 
206+ 
207+  **Option 2:** Manual installation - download the appropriate binary for your platform and Binary Ninja version, then place it in your Binary Ninja plugins directory. 
208+ 
209+  **Naming format:** 
210+  - Stable: \`NativePredicateSolver-<version>.<ext>\` 
211+  - Dev: \`NativePredicateSolver-dev.<ext>\` 
212+ 
213+  Where \`<ext>\` is \`dll\` (Windows), \`so\` (Linux), or \`dylib\` (macOS). 
214+  EOF 
215+ 
216+ name : Create Release 
217+  uses : softprops/action-gh-release@v1 
218+  with :
219+  tag_name : build-${{ github.run_number }} 
220+  name : Build ${{ github.run_number }} 
221+  body_path : release_notes.md 
222+  files : release_files/* 
223+  env :
224+  GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} 
0 commit comments