diff --git a/.github/workflows/build-and-push-binaries.yml b/.github/workflows/build-and-push-binaries.yml new file mode 100644 index 00000000..9bb4693f --- /dev/null +++ b/.github/workflows/build-and-push-binaries.yml @@ -0,0 +1,114 @@ +name: Build and Publish Binaries + +on: + workflow_dispatch: + inputs: + use_latest_release: + type: boolean + default: true + description: Upload binaries to the most recent release + pattern: + type: string + default: 'v*' + description: Pick from tags matching this pattern + pre_release: + type: boolean + description: Look for pre-release? + default: false + pull_request: + push: +jobs: + e2e_test: + name: Run e2e test + strategy: + matrix: + runs_on: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: cmd + runs-on: ${{ matrix.runs_on.os }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - id: release_info + uses: joutvhu/get-release@v1 + with: + latest: ${{ github.event.inputs.use_latest_release }} + pattern: ${{ github.event.inputs.pattern }} + prerelease: ${{ github.event.inputs.pre_release }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + check-latest: true + + - name: Set up venv (windows) + if: matrix.runs_on.os == 'windows-latest' + run: | + python -m venv venv + . venv\Scripts\activate + echo PATH=$PATH >> $GITHUB_ENV + + - name: Set up venv (linux & mac) + if: matrix.runs_on.os != 'windows-latest' + run: | + python -m venv venv + . venv/bin/activate + echo PATH=$PATH >> $GITHUB_ENV + + - name: Build RPC server + run: | + pip install -r requirements.txt + pip install pyinstaller + pip install -e . + pyinstaller build/build.spec + + - name: Build Kai Analyzer + run: | + cd kai-analyzer && go build -ldflags="-extldflags=-static" -o kai-analyzer main.go && cd .. + + - name: lowercase runner.os (linux & mac) + if: matrix.runs_on.os != 'windows-latest' && github.event_name == 'workflow_dispatch' + run: | + echo "OS=`echo ${{ runner.os }} | tr '[:upper:]' '[:lower:]'`" >>${GITHUB_ENV} + + - name: lowercase runner.os (windows) + if: matrix.runs_on.os == 'windows-latest' && github.event_name == 'workflow_dispatch' + run: | + $os_string = "${{ runner.os }}" + $lowercase_os_string = $os_string.ToLower() + echo "OS=$lowercase_os_string" >> $env:GITHUB_ENV + + - name: Archive binaries (linux & mac) + if: matrix.runs_on.os != 'windows-latest' && github.event_name == 'workflow_dispatch' + run: | + zip -j kai-rpc-server.${{ env.OS }}.zip dist/kai-rpc-server kai-analyzer/kai-analyzer + + - name: Archive binaries (windows) + if: matrix.runs_on.os == 'windows-latest' && github.event_name == 'workflow_dispatch' + run: | + mv kai-analyzer\kai-analyzer kai-analyzer\kai-analyzer.exe + $filesToInclude = "dist\kai-rpc-server.exe", "kai-analyzer\kai-analyzer.exe" + Compress-Archive -Path $filesToInclude -Destination kai-rpc-server.${{ env.OS }}.zip + + - name: Upload binary + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.release_info.outputs.upload_url }} + asset_path: kai-rpc-server.${{ env.OS }}.zip + asset_name: kai-rpc-server.${{ env.OS }}.zip + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore index aa8f32ff..fdb97bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,10 @@ __pycache__/ *.py[cod] *$py.class +#pyinstaller +build/build/ +dist/ + # C extensions *.so diff --git a/build/build.spec b/build/build.spec new file mode 100644 index 00000000..02462bda --- /dev/null +++ b/build/build.spec @@ -0,0 +1,56 @@ +# -*- mode: python ; coding: utf-8 -*- + +# This is a PyInstaller build spec to build Kai Client into a binary +# To run this spec, activate Kai venv and run `pyinstaller ./build.spec` + +import sys +import os +from PyInstaller.building.datastruct import Tree +from PyInstaller.building.build_main import Analysis +from PyInstaller.building.api import PYZ, EXE, COLLECT +from PyInstaller.utils.hooks import collect_data_files + +data_dirs = [ + ('../kai_solution_server/data/templates', 'data/templates'), +] + +script_path = '../kai/rpc_server/main.py' + +a = Analysis( + [script_path], + pathex=[os.path.dirname(script_path), '../'], + binaries=[], + datas=data_dirs, + hiddenimports=["_ssl"], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + # cipher=None, + noarchive=False, +) + +pyz = PYZ(a.pure, a.zipped_data) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name="kai-rpc-server", + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) +