Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
75 changes: 35 additions & 40 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,9 @@ concurrency:

jobs:
build:
name: ${{ matrix.name }}
name: macOS
runs-on: macos-26
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- name: macOS
slug: macos
destination: generic/platform=macOS
extra_args: ARCHS=arm64e ONLY_ACTIVE_ARCH=YES
- name: iOS
slug: ios
destination: generic/platform=iOS
extra_args: ""
- name: iOS Simulator
slug: ios-sim
destination: generic/platform=iOS Simulator
extra_args: ""
- name: tvOS
slug: tvos
destination: generic/platform=tvOS
extra_args: ""
- name: tvOS Simulator
slug: tvos-sim
destination: generic/platform=tvOS Simulator
extra_args: ""

steps:
- name: Checkout
Expand All @@ -52,29 +28,48 @@ jobs:
run: xcodebuild -version

- name: Validate Release Workflow
if: matrix.slug == 'macos'
run: bash Scripts/test-release-workflow.sh

- name: Install xcbeautify
run: brew install xcbeautify

- name: Sync Derived Source
run: bash Scripts/sync-derived-source.sh

# The package only mirrors LookinCore for the app (the Server is built
# and published from LookInside-Server).
- name: Build SwiftPM Products
if: matrix.slug == 'macos'
run: |
swift build -c debug --product LookinServerDynamic
swift build -c debug --product LookinServerInjected
run: swift build -c debug --product LookinShared

- name: Test Gesture Capture Models
run: bash Scripts/test-gesture-models.sh

- name: Build LookinServerInjected
- name: Test Activation Package
working-directory: Packages/LookInsideActivation
run: swift test

- name: Build LookInside
run: |
xcodebuild \
-workspace LookInside.xcworkspace \
-scheme LookinServerInjected \
-project LookInside.xcodeproj \
-scheme LookInside \
-configuration Debug \
-destination "${{ matrix.destination }}" \
-derivedDataPath "$RUNNER_TEMP/DerivedData/${{ matrix.slug }}" \
-destination 'generic/platform=macOS' \
-derivedDataPath "$RUNNER_TEMP/DerivedData" \
-skipMacroValidation \
CODE_SIGNING_ALLOWED=NO \
${{ matrix.extra_args }} \
build | xcbeautify
build

secret_scan:
name: Secret Scan
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Test Private Key Scanner
run: bash Scripts/test-scan-private-keys.sh

- name: Scan Repository For Secrets
run: bash Scripts/run-gitleaks.sh .
22 changes: 22 additions & 0 deletions .github/workflows/publish-existing-appcast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ jobs:
shasum -a 256 "$app_zip" | tee dist/checksums.txt
echo "app_zip=$app_zip" >> "$GITHUB_OUTPUT"

- name: Scan App Zip For Private Keys
run: bash app/Scripts/scan-private-keys.sh "${{ steps.artifact.outputs.app_zip }}"

- name: Validate Sparkle Publishing Secrets
env:
LOOKINSIDE_WEB_RELEASE_TOKEN: ${{ secrets.LOOKINSIDE_WEB_RELEASE_TOKEN }}
Expand All @@ -105,6 +108,10 @@ jobs:
ref: main
path: secrets
token: ${{ secrets.LOOKINSIDE_SECRETS_READ_TOKEN }}
sparse-checkout: sparkle
sparse-checkout-cone-mode: true
filter: blob:none
persist-credentials: false

- name: Export GitHub Release Notes
env:
Expand Down Expand Up @@ -152,6 +159,21 @@ jobs:
--version "${{ inputs.version }}" \
--asset-download-url "${{ inputs.asset_download_url }}"

- name: Scan Web Changes For Private Keys
run: |
set -euo pipefail
bash app/Scripts/scan-private-keys.sh web/public
sparkle_key="$(tr -d '[:space:]' <"$RUNNER_TEMP/sparkle-private-ed-key.txt")"
[[ -n "$sparkle_key" ]] || { echo "Decrypted Sparkle private key is empty." >&2; exit 1; }
if grep -rqF -- "$sparkle_key" web; then
echo "The Sparkle private key was written into the Web repository." >&2
exit 1
fi

- name: Remove Sparkle Private Key
if: always()
run: rm -f "$RUNNER_TEMP/sparkle-private-ed-key.txt"

- name: Commit Web Appcast
working-directory: web
run: |
Expand Down
112 changes: 54 additions & 58 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ jobs:
artifact_name: ${{ steps.context.outputs.artifact_name }}
source_ref: ${{ steps.context.outputs.source_ref }}
injector_ref: ${{ steps.context.outputs.injector_ref }}
mcp_ref: ${{ steps.context.outputs.mcp_ref }}
release_ref: ${{ steps.context.outputs.release_ref }}

steps:
- name: Validate Trigger Actor
Expand All @@ -42,7 +40,6 @@ jobs:
BUILD_NUMBER="${{ github.event.client_payload.build_number }}"
SOURCE_REF="${{ github.event.client_payload.source_ref }}"
INJECTOR_REF="${{ github.event.client_payload.injector_ref }}"
MCP_REF="${{ github.event.client_payload.mcp_ref }}"
RELEASE_REF="${{ github.event.client_payload.release_ref }}"
PARENT_REPOSITORY="${{ github.event.client_payload.parent_repository }}"
PARENT_REF="${{ github.event.client_payload.parent_ref }}"
Expand All @@ -65,7 +62,6 @@ jobs:
[[ "$PARENT_SHA" =~ ^[0-9a-f]{40}$ ]] || { echo "Invalid parent SHA." >&2; exit 1; }
[[ "$SOURCE_REF" =~ ^[0-9a-f]{40}$ ]] || { echo "Invalid Host source SHA." >&2; exit 1; }
[[ "$INJECTOR_REF" =~ ^[0-9a-f]{40}$ ]] || { echo "Invalid Injector source SHA." >&2; exit 1; }
[[ "$MCP_REF" =~ ^[0-9a-f]{40}$ ]] || { echo "Invalid MCP source SHA." >&2; exit 1; }
[[ "$RELEASE_REF" =~ ^[0-9a-f]{40}$ ]] || { echo "Invalid Release source SHA." >&2; exit 1; }
[[ "$RELEASE_ID" == "release/app/$VERSION@$PARENT_SHA/host" ]] || {
echo "Release id does not identify the parent tag and commit." >&2
Expand All @@ -79,8 +75,6 @@ jobs:
echo "artifact_name=LookInside-${VERSION}-release"
echo "source_ref=${SOURCE_REF}"
echo "injector_ref=${INJECTOR_REF}"
echo "mcp_ref=${MCP_REF}"
echo "release_ref=${RELEASE_REF}"
} >>"${GITHUB_OUTPUT}"

build_package:
Expand All @@ -101,6 +95,9 @@ jobs:
fetch-depth: 0
ref: ${{ needs.prepare.outputs.source_ref }}

- name: Scan Repository For Secrets
run: bash Scripts/run-gitleaks.sh .

- name: Show Xcode Version
run: xcodebuild -version

Expand Down Expand Up @@ -133,21 +130,6 @@ jobs:
git -C ../LookInside-Injector checkout --detach "${{ needs.prepare.outputs.injector_ref }}"
[[ "$(git -C ../LookInside-Injector rev-parse HEAD)" == "${{ needs.prepare.outputs.injector_ref }}" ]]

- name: Checkout MCP Server
env:
LOOKINSIDE_MCP_READ_TOKEN: ${{ secrets.LOOKINSIDE_PRIVATE_READ_TOKEN || secrets.LOOKINSIDE_WEB_RELEASE_TOKEN || secrets.LOOKINSIDE_INJECTOR_READ_TOKEN }}
run: |
set -euo pipefail
if [[ -z "${LOOKINSIDE_MCP_READ_TOKEN}" ]]; then
echo "LOOKINSIDE_PRIVATE_READ_TOKEN, LOOKINSIDE_WEB_RELEASE_TOKEN, or LOOKINSIDE_INJECTOR_READ_TOKEN is required to checkout LookInside-MCP." >&2
exit 1
fi
git clone --no-checkout \
"https://x-access-token:${LOOKINSIDE_MCP_READ_TOKEN}@github.com/LookInsideApp/LookInside-MCP.git" \
../LookInside-MCP
git -C ../LookInside-MCP checkout --detach "${{ needs.prepare.outputs.mcp_ref }}"
[[ "$(git -C ../LookInside-MCP rev-parse HEAD)" == "${{ needs.prepare.outputs.mcp_ref }}" ]]

- name: Configure Private Package Access
env:
LOOKINSIDE_PRIVATE_READ_TOKEN: ${{ secrets.LOOKINSIDE_PRIVATE_READ_TOKEN || secrets.LOOKINSIDE_WEB_RELEASE_TOKEN || secrets.LOOKINSIDE_INJECTOR_READ_TOKEN }}
Expand Down Expand Up @@ -185,6 +167,11 @@ jobs:
--tag "${{ needs.prepare.outputs.build_version }}" \
--stage archive-app

- name: Check Release Build For Debug Overrides
run: |
bash Scripts/check-host-release-clean.sh --release-strict \
"build/releases/${{ needs.prepare.outputs.build_version }}/LookInside.xcarchive"

- name: Package Unsigned Archive
run: |
set -euo pipefail
Expand All @@ -193,6 +180,11 @@ jobs:
-C "${release_dir}" \
LookInside.xcarchive

- name: Scan Unsigned Archive For Private Keys
run: |
bash Scripts/scan-private-keys.sh \
"build/releases/${{ needs.prepare.outputs.build_version }}/LookInside.xcarchive.tar.gz"

- name: Upload Unsigned Artifacts
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -263,6 +255,16 @@ jobs:
--tag "${{ needs.prepare.outputs.build_version }}" \
--stage notarize-app

- name: Scan Notarized App For Private Keys And Debug Overrides
run: |
set -euo pipefail
shopt -s nullglob
release_dir="build/releases/${{ needs.prepare.outputs.build_version }}"
app_zips=("${release_dir}"/LookInside-*-macOS-app.zip)
[[ ${#app_zips[@]} -gt 0 ]] || { echo "No notarized app zip to scan." >&2; exit 1; }
bash Scripts/scan-private-keys.sh "${app_zips[@]}"
bash Scripts/check-host-release-clean.sh --release-strict "${app_zips[@]}"

- name: Upload Notarized App
uses: actions/upload-artifact@v4
with:
Expand All @@ -277,6 +279,14 @@ jobs:
timeout-minutes: 20

steps:
- name: Checkout Release Scripts
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.source_ref }}
path: app
sparse-checkout: Scripts
persist-credentials: false

- name: Download App Artifact
uses: actions/download-artifact@v4
with:
Expand All @@ -288,6 +298,9 @@ jobs:
cd dist
shasum -a 256 ./*.zip > checksums.txt

- name: Scan Release Artifacts For Private Keys
run: bash app/Scripts/scan-private-keys.sh dist

- name: Upload Notarized Artifacts
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -393,42 +406,10 @@ jobs:
ref: main
path: secrets
token: ${{ secrets.LOOKINSIDE_SECRETS_READ_TOKEN }}

- name: Checkout Release Tools
uses: actions/checkout@v4
with:
repository: LookInsideApp/LookInside-Release
ref: ${{ needs.prepare.outputs.release_ref }}
path: release-tools
token: ${{ secrets.LOOKINSIDE_WEB_RELEASE_TOKEN }}

- name: Download Pinned Auth Server Publication
env:
GH_TOKEN: ${{ secrets.LOOKINSIDE_WEB_RELEASE_TOKEN }}
run: |
set -euo pipefail
mkdir -p auth-artifact
for asset in \
lookinside-auth-server.app.zip \
lookinside-auth-server.app.zip.sha256 \
lookinside-auth-server.app.zip.version; do
gh release download storage \
--repo LookInsideApp/LookInside-Release \
--pattern "$asset" \
--dir auth-artifact
done
[[ "$(tr -d '[:space:]' <auth-artifact/lookinside-auth-server.app.zip.version)" == "${{ needs.prepare.outputs.build_version }}" ]] || {
echo "Published Auth Server version does not match the app release." >&2
exit 1
}

- name: Stage Auth Server Metadata Into Web Repository
run: |
set -euo pipefail
bash release-tools/Scripts/sync-auth-server-assets-to-web.sh \
--web-dir web \
--asset auth-artifact/lookinside-auth-server.app.zip \
--url https://github.com/LookInsideApp/LookInside-Release/releases/download/storage/lookinside-auth-server.app.zip
sparse-checkout: sparkle
sparse-checkout-cone-mode: true
filter: blob:none
persist-credentials: false

- name: Export GitHub Release Notes
env:
Expand Down Expand Up @@ -477,13 +458,28 @@ jobs:
--version "${{ needs.prepare.outputs.build_version }}" \
--asset-download-url "$ASSET_DOWNLOAD_URL"

- name: Scan Web Changes For Private Keys
run: |
set -euo pipefail
bash app/Scripts/scan-private-keys.sh web/public
sparkle_key="$(tr -d '[:space:]' <"$RUNNER_TEMP/sparkle-private-ed-key.txt")"
[[ -n "$sparkle_key" ]] || { echo "Decrypted Sparkle private key is empty." >&2; exit 1; }
if grep -rqF -- "$sparkle_key" web; then
echo "The Sparkle private key was written into the Web repository." >&2
exit 1
fi

- name: Remove Sparkle Private Key
if: always()
run: rm -f "$RUNNER_TEMP/sparkle-private-ed-key.txt"

- name: Commit Web Appcast
working-directory: web
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add public/appcast.xml public/downloads/manifest.json public/downloads/auth-server public/downloads/lookinside
git add public/appcast.xml public/downloads/manifest.json public/downloads/lookinside
if git diff --cached --quiet; then
echo "No Web appcast changes to publish."
exit 0
Expand Down
2 changes: 1 addition & 1 deletion Configuration/Version.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
// LookInside
//

MARKETING_VERSION = 2.3.13
MARKETING_VERSION = 3.0.0
CURRENT_PROJECT_VERSION = 45
Loading
Loading