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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@ name: CI

on:
pull_request:
push:
branches:
- main
paths:
- ".github/workflows/*.yml"
- "apps/cloud/**"
- "apps/desktop/**"
- "apps/mesh-front-door/**"
- "packages/agent-sessions/**"
- "packages/cli/**"
- "packages/protocol/**"
- "packages/runtime/**"
- "packages/session-trace/**"
- "packages/session-trace-react/**"
- "packages/web/**"
- "scripts/**"
- "package.json"
- "bun.lock"
- "tsconfig*.json"
workflow_call:

permissions:
contents: read
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: Deploy to GitHub Pages
name: Deploy Site

on:
push:
branches: [main]
paths:
- ".github/workflows/deploy.yml"
- "landing/**"
- "package.json"
- "bun.lock"

permissions:
contents: read
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/release-app-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Release App iOS

on:
push:
tags:
- app-ios-v*
workflow_dispatch:

permissions:
contents: read

concurrency:
group: release-app-ios-${{ github.ref }}
cancel-in-progress: false

jobs:
app-store:
name: Upload to App Store Connect
runs-on: macos-latest
timeout-minutes: 60
environment: Production
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: "24.x"
package-manager-cache: false

- name: Install XcodeGen
run: brew install xcodegen

- name: Validate release target
shell: bash
run: |
set -euo pipefail

package_version="$(node -p "require('./package.json').version")"

if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then
expected="${GITHUB_REF_NAME#app-ios-v}"
if [[ "$expected" != "$package_version" ]]; then
echo "::error::Tag version $expected does not match package.json version $package_version."
exit 1
fi
fi

- name: Verify asc CLI
env:
OPENSCOUT_ASC_BIN: ${{ vars.OPENSCOUT_ASC_BIN || 'asc' }}
run: |
set -euo pipefail

if ! command -v "$OPENSCOUT_ASC_BIN" >/dev/null 2>&1; then
echo "::error::Missing App Store Connect CLI: $OPENSCOUT_ASC_BIN"
exit 1
fi

- name: Release to App Store Connect
env:
OPENSCOUT_ASC_APP_ID: ${{ vars.OPENSCOUT_ASC_APP_ID || '6761672978' }}
OPENSCOUT_ASC_BIN: ${{ vars.OPENSCOUT_ASC_BIN || 'asc' }}
run: bash apps/ios/scripts/release.sh
137 changes: 137 additions & 0 deletions .github/workflows/release-app-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Release App macOS

on:
push:
tags:
- app-macos-v*
workflow_dispatch:
inputs:
version:
description: "Version to release. Defaults to package.json."
required: false
upload_release:
description: "Create or update the GitHub release with the DMG."
type: boolean
required: false
default: true

permissions:
contents: write

concurrency:
group: release-app-macos-${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name || github.run_id }}
cancel-in-progress: false

jobs:
dmg:
name: Build signed and notarized DMG
runs-on: macos-latest
timeout-minutes: 45
environment: Production
steps:
- uses: actions/checkout@v6

- uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"

- name: Resolve release target
id: release
shell: bash
env:
INPUT_VERSION: ${{ inputs.version || '' }}
run: |
set -euo pipefail

if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
version="${INPUT_VERSION:-$(node -p "require('./package.json').version")}"
tag="app-macos-v${version}"
else
tag="$GITHUB_REF_NAME"
version="${tag#app-macos-v}"
fi

if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "::error::Release version must look like X.Y.Z, got: $version"
exit 1
fi

echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Import Developer ID certificate
shell: bash
env:
P12_BASE64: ${{ secrets.MACOS_DEVELOPER_ID_APPLICATION_P12_BASE64 }}
P12_PASSWORD: ${{ secrets.MACOS_DEVELOPER_ID_APPLICATION_P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.MACOS_RELEASE_KEYCHAIN_PASSWORD }}
run: |
set -euo pipefail

if [[ -z "$P12_BASE64" || -z "$P12_PASSWORD" || -z "$KEYCHAIN_PASSWORD" ]]; then
echo "::error::Missing macOS signing secrets."
exit 1
fi

keychain="$RUNNER_TEMP/openscout-release.keychain-db"
cert="$RUNNER_TEMP/developer-id-application.p12"

printf '%s' "$P12_BASE64" | base64 -d > "$cert"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain"
security set-keychain-settings -lut 21600 "$keychain"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain"
security import "$cert" -k "$keychain" -P "$P12_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
security list-keychains -d user -s "$keychain" "$HOME/Library/Keychains/login.keychain-db"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$keychain"

- name: Configure notarization profile
shell: bash
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
run: |
set -euo pipefail

if [[ -z "$APPLE_ID" || -z "$APPLE_TEAM_ID" || -z "$APPLE_APP_SPECIFIC_PASSWORD" ]]; then
echo "::error::Missing Apple notarization secrets."
exit 1
fi

xcrun notarytool store-credentials openscout-ci-notarytool \
--apple-id "$APPLE_ID" \
--team-id "$APPLE_TEAM_ID" \
--password "$APPLE_APP_SPECIFIC_PASSWORD"

- name: Build DMG
env:
VERSION: ${{ steps.release.outputs.version }}
OPENSCOUT_NOTARY_PROFILE: openscout-ci-notarytool
OPENSCOUT_SIGN_IDENTITY: ${{ vars.OPENSCOUT_SIGN_IDENTITY || '' }}
run: bash apps/macos/scripts/build-dmg.sh

- name: Upload DMG artifact
uses: actions/upload-artifact@v5
with:
name: OpenScoutMenu-${{ steps.release.outputs.version }}
path: apps/macos/dist/OpenScoutMenu-${{ steps.release.outputs.version }}.dmg
if-no-files-found: error

- name: Create or update GitHub release
if: ${{ github.event_name == 'push' || inputs.upload_release }}
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ steps.release.outputs.tag }}
RELEASE_VERSION: ${{ steps.release.outputs.version }}
run: |
set -euo pipefail

dmg="apps/macos/dist/OpenScoutMenu-${RELEASE_VERSION}.dmg"

if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
gh release upload "$RELEASE_TAG" "$dmg" --clobber
else
gh release create "$RELEASE_TAG" "$dmg" \
--title "OpenScout macOS ${RELEASE_VERSION}" \
--notes "Signed and notarized macOS app release."
fi
Loading
Loading