Skip to content

Ghidra Build

Ghidra Build #784

Workflow file for this run

name: Ghidra Build
on:
workflow_dispatch:
inputs:
repo:
description: Ghidra GitHub repository
default: NationalSecurityAgency/ghidra
required: true
prevRev:
description: 'Revision of the previous release'
required: false
rev:
description: 'Revision to build'
required: true
env:
GRADLE_VERSION: 8.5
JAVA_VERSION: 21
jobs:
build-natives:
strategy:
matrix:
include:
#- target: win_x86_32
# os: windows-latest
- target: win_x86_64
os: windows-latest
- target: linux_x86_64
os: ubuntu-latest
- target: linux_arm_64
os: ubuntu-latest
- target: mac_x86_64
os: macos-latest
- target: mac_arm_64
os: macos-latest
fail-fast: false
name: Build ${{ matrix.target }} Binaries
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.inputs.repo }}
ref: ${{ github.event.inputs.rev }}
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: ${{ env.JAVA_VERSION }}
- name: Install bison
if: ${{ matrix.os == 'windows-latest' }}
shell: pwsh
run: |
Invoke-WebRequest -URI "https://github.com/lexxmark/winflexbison/releases/download/v2.4.12/win_flex_bison-2.4.12.zip" -OutFile "win_flex_bison-2.4.12.zip"
Expand-Archive -Path "win_flex_bison-2.4.12.zip" -DestinationPath "winflexbison"
Rename-Item -Path "$pwd\winflexbison\win_bison.exe" -NewName "bison.exe"
Rename-Item -Path "$pwd\winflexbison\win_flex.exe" -NewName "flex.exe"
"$pwd\winflexbison" >> $env:GITHUB_PATH
- name: Checkout Ghidra-CI Repo
uses: actions/checkout@v4
with:
path: ghidra-ci
- uses: eskatos/gradle-command-action@v3
with:
gradle-version: ${{ env.GRADLE_VERSION }}
arguments: --init-script gradle/support/fetchDependencies.gradle init
- name: Setup Linux ARM toolchain
if: ${{ matrix.target == 'linux_arm_64' }}
run: |
sudo dpkg --add-architecture arm64
sudo bash -c 'echo "http://ports.ubuntu.com/ubuntu-ports/ priority:0" >> /etc/apt/apt-mirrors.txt'
sudo apt-get update
sudo apt-get install g++-aarch64-linux-gnu libc6-dev-arm64-cross zlib1g-dev:arm64
mkdir -p $HOME/.gradle
cp ghidra-ci/linux_arm_64.init.gradle $HOME/.gradle/init.gradle
- name: Setup MacOS ARM toolchain
if: ${{ matrix.target == 'mac_arm_64' }}
run: |
mkdir -p $HOME/.gradle
cp ghidra-ci/mac_arm_64.init.gradle $HOME/.gradle/init.gradle
- uses: eskatos/gradle-command-action@v3
with:
gradle-version: ${{ env.GRADLE_VERSION }}
arguments: buildNatives_${{ matrix.target }}
- name: "Sign macOS binaries"
if: ${{ env.MACOS_CODESIGN_CRT_PWD != '' && (matrix.target == 'mac_arm_64' || matrix.target == 'mac_x86_64') }}
run: |
echo "$MACOS_CODESIGN_CRT" | base64 -d > certificate.p12
security create-keychain -p test123 build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p test123 build.keychain
security import certificate.p12 -k build.keychain -P "$MACOS_CODESIGN_CRT_PWD" -T /usr/bin/codesign
rm certificate.p12
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k test123 build.keychain
for file in $(find . -path "*/build/os/${{ matrix.target }}/*" -type f); do
echo "Signing file $file"
/usr/bin/codesign --force -s "$MACOS_CODESIGN_CRT_IDENTITY" --options runtime "$file" -v
done
security lock-keychain build.keychain
security default-keychain -s
security delete-keychain build.keychain
env:
MACOS_CODESIGN_CRT: ${{ secrets.MACOS_CODESIGN_CRT }}
MACOS_CODESIGN_CRT_PWD: ${{ secrets.MACOS_CODESIGN_CRT_PWD }}
MACOS_CODESIGN_CRT_IDENTITY: ${{ secrets.MACOS_CODESIGN_CRT_IDENTITY }}
# Apparently, github is an incompetent idiot that can't handle permissions
# properly. https://github.com/actions/upload-artifact/issues/38
# Wrap the binaries in a tar archive to fix that.
- name: Tar the binaries
run: tar -cvf "${{matrix.target}}.build.tar" $(find . -path "*/build/os/${{ matrix.target }}/*" -type f)
shell: bash
- name: "Notarize macOS binaries"
if: ${{ env.MACOS_APPLE_USERNAME != '' && (matrix.target == 'mac_arm_64' || matrix.target == 'mac_x86_64') }}
run: |
for file in $(find . -path "*/build/os/${{ matrix.target }}/*" -type f); do
echo "Notarizing file $file"
ditto -c -k "$file" "${file}.zip"
xcrun notarytool submit --apple-id "$MACOS_APPLE_USERNAME" --password "$MACOS_APPLE_PASSWORD" --team-id "$MACOS_APPLE_TEAMID" --wait "${file}.zip"
rm "${file}.zip"
done
env:
MACOS_APPLE_USERNAME: ${{ secrets.MACOS_APPLE_USERNAME }}
MACOS_APPLE_PASSWORD: ${{ secrets.MACOS_APPLE_PASSWORD }}
MACOS_APPLE_TEAMID: ${{ secrets.MACOS_APPLE_TEAMID }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: natives-${{ matrix.target }}
path: "${{matrix.target}}.build.tar"
dist:
name: "Build Ghidra distributable zip"
needs: ["build-natives"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.inputs.repo }}
ref: ${{ github.event.inputs.rev }}
fetch-depth: 0
- name: Download native binaries
uses: actions/download-artifact@v4
with:
pattern: natives-*
merge-multiple: true
- name: Extract all binaries
run: |
for file in *.build.tar; do
echo "Extracting $file"
tar xvf "$file"
done
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: ${{ env.JAVA_VERSION }}
- name: Fetch the Ghidra dependencies.
uses: eskatos/gradle-command-action@v3
with:
gradle-version: ${{ env.GRADLE_VERSION }}
arguments: --init-script gradle/support/fetchDependencies.gradle init
# TODO: Pre-build GhidraDev
- name: Checkout ghidra-data
uses: actions/checkout@v4
with:
repository: NationalSecurityAgency/ghidra-data
path: 'ghidra-data'
- name: Copy ghidra-data files into the appropriate directories
run: cp -r ghidra-data/FunctionID/* Ghidra/Features/FunctionID/data
- name: Build ghidra, create a cross-platform distribution
uses: eskatos/gradle-command-action@v3
with:
gradle-version: ${{ env.GRADLE_VERSION }}
arguments: -x ip -PallPlatforms buildGhidra
# TODO: remove upload-artifact when create release is sure to work
- name: Upload final dist
uses: actions/upload-artifact@v4
with:
path: "build/dist/*"
- name: Remove temporary artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: natives-*
- name: Get current date, rev and dist name
id: date
run: |
echo date=$(date +'%Y-%m-%d') >> $GITHUB_OUTPUT
echo dist=$(ls build/dist) >> $GITHUB_OUTPUT
echo rev=$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
with:
path: ghidra-ci
- name: Generate CHANGELOG.md
if: ${{ inputs.prevRev != '' }}
run: |
cd ghidra-ci
sudo apt-get update
sudo apt-get install libkrb5-dev
npm i
node generate_changelog.js ${{ github.event.inputs.repo }} ${{github.event.inputs.prevRev}} ${{github.event.inputs.rev}} > CHANGELOG.md
- name: Generate fallback CHANGELOG.md
if: ${{ inputs.prevRev == '' }}
run: |
cd ghidra-ci
echo "# Changelog" > CHANGELOG.md
echo "Built from [${{ inputs.repo }}@${{ inputs.rev }}](https://github.com/${{ inputs.repo }}/commit/${{ inputs.rev }})" >> CHANGELOG.md
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.date.outputs.date }}
release_name: Release ${{ steps.date.outputs.date }}(${{ steps.date.outputs.rev }})
body_path: ./ghidra-ci/CHANGELOG.md
# TODO: This is a horrible hack.
commitish: "master"
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./build/dist/${{ steps.date.outputs.dist }}
asset_name: release.zip
asset_content_type: application/zip