Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: macOS executable #28

Merged
merged 31 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
72ddd89
feat: macOS executable
tnunamak Mar 8, 2024
f898304
Try FlyCI
tnunamak Mar 8, 2024
0194dd3
Update package.yml
tnunamak Mar 8, 2024
c386d3b
Update package.yml
tnunamak Mar 8, 2024
85ccd73
Collect connector files
tnunamak Mar 8, 2024
8448efd
Update selfie.spec
tnunamak Mar 8, 2024
7c81561
Build executables manually
tnunamak Mar 11, 2024
267b596
Attempt to notarize macOS app
Mar 12, 2024
71da397
Attempt to notarize macOS app
Mar 12, 2024
6641a94
Log error output
tnunamak Mar 15, 2024
fb94b1d
More notarization debugging
tnunamak Mar 15, 2024
95a8f65
Remove quotations, just in case
tnunamak Mar 15, 2024
d20a1a4
Notarize with API key
tnunamak Mar 15, 2024
3e718f4
Fix notarization status parsing
tnunamak Mar 15, 2024
30f2caf
Build macOS bundle with pyinstaller
tnunamak Mar 15, 2024
600f316
Miss a reference
tnunamak Mar 15, 2024
d57c9e9
Merge remote-tracking branch 'origin/main' into package
tnunamak Mar 19, 2024
aa8cd43
Create a system tray launcher
tnunamak Mar 20, 2024
c593ba9
Fix logic error
tnunamak Mar 20, 2024
76e213c
Expose logs
tnunamak Mar 20, 2024
15de3fc
Ensure selfie.log is writable
tnunamak Mar 20, 2024
75bcb1c
Preemptive litellm fix
tnunamak Mar 20, 2024
a1d288d
Lower litellm version
tnunamak Mar 20, 2024
9683cef
Log uvicorn output to selfie.log
tnunamak Mar 20, 2024
dafb7bf
More logging
tnunamak Mar 20, 2024
6f56e34
Externalize data
tnunamak Mar 27, 2024
ed48f80
feat: release-please (#37)
tnunamak Mar 30, 2024
496cb67
Update selfie/utils/filesystem.py
tnunamak Mar 30, 2024
3daea25
Update .github/actions/build-action/action.yml
tnunamak Mar 30, 2024
2498e6a
Update selfie/__main__.py
tnunamak Mar 30, 2024
527b216
Update selfie/config.py
tnunamak Mar 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions .github/actions/build-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: 'Build Action'
description: 'Composite action to build the Selfie package'

inputs:
release_tag:
description: 'The tag name of the release'
required: false

runs:
using: 'composite'
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Determine target filename
run: |
echo "TARGET_NAME=Selfie-${{ runner.os }}-$(uname -m).zip" >> $GITHUB_ENV
shell: bash

- name: Install the Apple certificate and provisioning profile
if: runner.os == 'macOS'
env:
APPLE_BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
APPLE_BUILD_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }}
APPLE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }}
APPLE_MACOS_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_MACOS_KEYCHAIN_PASSWORD }}
run: |
CERTIFICATE_PATH=$RUNNER_TEMP/apple_certificate.p12
PROVISIONING_PROFILE_PATH=$RUNNER_TEMP/apple_provisioning_profile.provisionprofile
KEYCHAIN_PATH=$RUNNER_TEMP/github-actions.keychain-db
KEYCHAIN_NAME=github-actions

echo -n "$APPLE_BUILD_CERTIFICATE_BASE64" | base64 --decode > $CERTIFICATE_PATH
echo -n "$APPLE_PROVISIONING_PROFILE_BASE64" | base64 --decode > $PROVISIONING_PROFILE_PATH

security create-keychain -p "$APPLE_MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$APPLE_MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security default-keychain -s $KEYCHAIN_PATH

security import $CERTIFICATE_PATH -P "$APPLE_BUILD_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$APPLE_MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PROVISIONING_PROFILE_PATH ~/Library/MobileDevice/Provisioning\ Profiles
shell: bash

- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
shell: bash

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: poetry
cache-dependency-path: poetry.lock

- name: Install dependencies with Poetry
run: poetry install --no-dev
shell: bash

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'
cache-dependency-path: selfie-ui/yarn.lock

- name: Cache Next.js build artifacts
uses: actions/cache@v4
with:
path: |
selfie-ui/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('selfie-ui/**/yarn.lock') }}-${{ hashFiles('selfie-ui/**/*.js', 'selfie-ui/**/*.jsx', 'selfie-ui/**/*.ts', 'selfie-ui/**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('selfie-ui/**/yarn.lock') }}-

- name: Build the Selfie UI
run: sh scripts/build-ui.sh
shell: bash

- name: Install PyInstaller
run: poetry run pip install pyinstaller
shell: bash

- name: Build with PyInstaller
run: poetry run pyinstaller selfie.spec --noconfirm
shell: bash

- name: Set executable permissions
run: chmod +x dist/selfie/selfie
shell: bash

- name: Build macOS App
if: runner.os == 'macOS'
env:
APPLE_ASC_API_KEY_KEY_BASE64: ${{ secrets.APPLE_ASC_API_KEY_KEY_BASE64 }}
run: |
sh scripts/package-macos-app.sh

ditto -c -k --keepParent "${{ github.workspace }}/dist/Selfie.app" "${{ env.TARGET_NAME }}.zip"

API_KEY_PATH=$RUNNER_TEMP/AuthKey_${{secrets.APPLE_ASC_API_KEY_ID}}.p8
echo -n "$APPLE_ASC_API_KEY_KEY_BASE64" | base64 --decode > $API_KEY_PATH

NOTARIZATION_OUTPUT=$(xcrun notarytool submit "${{ env.TARGET_NAME }}.zip" --issuer ${{ secrets.APPLE_ASC_API_KEY_ISSUER_UUID }} --key-id ${{ secrets.APPLE_ASC_API_KEY_ID }} --key $API_KEY_PATH --wait 2>&1)

REQUEST_UUID=$(echo "${NOTARIZATION_OUTPUT}" | grep 'id:' | awk '{print $NF}')
NOTARIZATION_STATUS=$(echo "${NOTARIZATION_OUTPUT}" | grep 'status:' | tail -n 1 | awk '{print $NF}')

if [[ -z "$REQUEST_UUID" ]]; then
echo "Failed to submit app for notarization. Full output:"
echo "${NOTARIZATION_OUTPUT}"
exit 1
else
echo "Notarization submitted; RequestUUID: ${REQUEST_UUID}"
fi

if [[ "$NOTARIZATION_STATUS" == "Invalid" ]]; then
echo "Notarization failed with status: ${NOTARIZATION_STATUS}"
echo "Fetching notarization log for RequestUUID: ${REQUEST_UUID}..."
xcrun notarytool log ${REQUEST_UUID} --key $API_KEY_PATH --key-id ${{ secrets.APPLE_ASC_API_KEY_ID }} --issuer ${{ secrets.APPLE_ASC_API_KEY_ISSUER_UUID }}
exit 1
elif [[ "$NOTARIZATION_STATUS" != "Accepted" ]]; then
echo "Notarization failed with an unexpected status: ${NOTARIZATION_STATUS}"
echo "Full notarization output:"
echo "${NOTARIZATION_OUTPUT}"
exit 1
else
echo "Notarization successful; status: ${NOTARIZATION_STATUS}"
fi

xcrun stapler staple "${{ github.workspace }}/dist/Selfie.app"

ditto -c -k --keepParent "${{ github.workspace }}/dist/Selfie.app" "${{ env.TARGET_NAME }}.zip"
shell: bash

- name: Build Non-macOS App
if: runner.os != 'macOS'
run: zip -r Selfie-${{ runner.os }}.zip dist/selfie
shell: bash

- name: Upload Artifact
uses: actions/upload-artifact@v4
if: inputs.release_tag == ''
with:
name: ${{ env.TARGET_NAME }}
path: ${{ env.TARGET_NAME }}.zip
overwrite: true
if-no-files-found: error

- name: Upload Release Asset
if: inputs.release_tag != ''
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release upload ${{ inputs.release_tag }} ${{ env.TARGET_NAME }}.zip
shell: bash

- name: Clean up keychain and provisioning profile
if: runner.os == 'macOS'
run: |
security delete-keychain $RUNNER_TEMP/github-actions.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/apple_provisioning_profile.provisionprofile
shell: bash
16 changes: 16 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Build Packages

on:
workflow_dispatch:

jobs:
build:
name: Build on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, macos-latest-xlarge]

steps:
- name: Build package
uses: ./.github/actions/build-action
44 changes: 44 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Release Please

on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest

outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}

steps:
- uses: google-github-actions/release-please-action@v4
id: release
with:
token: ${{ secrets.SERVICE_ACCOUNT_PAT }}
release-type: python

build:
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}

strategy:
matrix:
os: [macos-latest, macos-latest-xlarge]

runs-on: ${{ matrix.os }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build and upload release assets
uses: ./.github/actions/build-action
with:
release_tag: ${{ needs.release-please.outputs.tag_name }}
Binary file added Selfie.icns
Binary file not shown.
9 changes: 0 additions & 9 deletions hooks/hook-llama_index.py

This file was deleted.

93 changes: 82 additions & 11 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading