mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
chore(cloud-integration): packaged integration builds honor the dev sandbox key; sync merges forward, never force-pushes
This commit is contained in:
@@ -3,11 +3,11 @@ import { resolve } from 'node:path'
|
||||
|
||||
/** Integration-branch backends baked into main (packaged builds read no shell env); build-time env overrides the file. */
|
||||
export function cloudBuildDefaultsDefine(env: NodeJS.ProcessEnv = process.env): string {
|
||||
const file: { billingApiUrl?: string; cloudSandboxUrl?: string } = JSON.parse(
|
||||
readFileSync(resolve('config/cloud-build-defaults.json'), 'utf8')
|
||||
)
|
||||
const file: { billingApiUrl?: string; cloudSandboxUrl?: string; allowDevSigning?: boolean } =
|
||||
JSON.parse(readFileSync(resolve('config/cloud-build-defaults.json'), 'utf8'))
|
||||
return JSON.stringify({
|
||||
billingApiUrl: env.ORCA_BUILD_BILLING_API_URL || file.billingApiUrl,
|
||||
cloudSandboxUrl: env.ORCA_BUILD_CLOUD_SANDBOX_URL || file.cloudSandboxUrl
|
||||
cloudSandboxUrl: env.ORCA_BUILD_CLOUD_SANDBOX_URL || file.cloudSandboxUrl,
|
||||
allowDevSigning: file.allowDevSigning === true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"_comment": "Integration-branch only (stablyai/orca-private cloud/integration). Public dev endpoints baked into packaged builds; no secrets. ORCA_BUILD_BILLING_API_URL / ORCA_BUILD_CLOUD_SANDBOX_URL at build time, or ORCA_BILLING_API_URL / ORCA_CLOUD_SANDBOX_URL at run time, override them.",
|
||||
"_comment": "Integration-branch only (stablyai/orca-private cloud/integration). Public dev endpoints baked into packaged builds; no secrets. ORCA_BUILD_BILLING_API_URL / ORCA_BUILD_CLOUD_SANDBOX_URL at build time, or ORCA_BILLING_API_URL / ORCA_CLOUD_SANDBOX_URL at run time, override them. allowDevSigning lets this packaged build honor ORCA_CLOUD_SANDBOX_DEV_KEY_FILE (dev operator key) until login.onorca.dev ships the sandbox-token endpoint; the key itself is never in git.",
|
||||
"billingApiUrl": "https://orca-billing-dev.lovecast.workers.dev",
|
||||
"cloudSandboxUrl": "https://orca-sandbox-control-dev.lovecast.workers.dev"
|
||||
"cloudSandboxUrl": "https://orca-sandbox-control-dev.lovecast.workers.dev",
|
||||
"allowDevSigning": true
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# Rebuild cloud/integration (pushed only to nwparker/orca-private) from scratch:
|
||||
# stablyai/orca main
|
||||
# + merge nwparker/orca-private nwparker/accounts-billing, nwparker/vercel-driver
|
||||
# + merge open upstream PR branches still under review (stablyai/orca nwparker/agent-host-sign-in #40228,
|
||||
# nwparker/agent-api-keys #40303); drop each from STACKED once it lands on main
|
||||
# + cherry-pick every "chore(cloud-integration)" commit already on cloud/integration (build defaults, this script).
|
||||
# Move cloud/integration (on `private` = nwparker/orca-private) forward. Other workstreams branch from it and merge
|
||||
# into it, so it is NEVER rebuilt or force-pushed: this script only merges new commits from its sources.
|
||||
# stablyai/orca main (origin)
|
||||
# + nwparker/orca-private nwparker/accounts-billing, nwparker/vercel-driver (until they are retired)
|
||||
# + open upstream PR branches stacked in while under review: nwparker/agent-host-sign-in (#40228),
|
||||
# nwparker/agent-api-keys (#40303). Once a PR lands, main brings it; drop it from STACKED.
|
||||
# Never based on stablyai/orca-private (Bots). git rerere replays conflict resolutions made before in this clone.
|
||||
# Conflict policy: billing files (cloud/apps/billing, cloud/docs/accounts-billing-design.md, src/main/billing,
|
||||
# src/renderer/src/components/billing, src/shared/orca-billing.ts, billing keys in en.json) keep accounts-billing
|
||||
# ("ours"); vercel-driver carries an older billing snapshot. Elsewhere keep both sides.
|
||||
# src/renderer/src/components/billing, src/shared/orca-billing.ts, billing keys in en.json) keep accounts-billing;
|
||||
# vercel-driver carries an older billing snapshot. Elsewhere keep both sides.
|
||||
#
|
||||
# Usage (from a clone of stablyai/orca with remote `private` = nwparker/orca-private, never an Orca worktree):
|
||||
# config/scripts/cloud-integration/sync-cloud-integration.sh # builds local branch cloud/integration-next
|
||||
# on conflict: resolve, `git add -A && git commit --no-edit` (or `git cherry-pick --continue`), rerun with --resume
|
||||
# pnpm install --frozen-lockfile && pnpm typecheck && pnpm lint
|
||||
# git push --force-with-lease=cloud/integration private cloud/integration-next:cloud/integration
|
||||
# Usage (clone of stablyai/orca as origin, remote `private`; never an Orca worktree):
|
||||
# config/scripts/cloud-integration/sync-cloud-integration.sh
|
||||
# on conflict: resolve, `git add -A && git commit --no-edit`, rerun (already-merged sources are skipped)
|
||||
# then: pnpm install --frozen-lockfile && pnpm typecheck && pnpm lint && targeted vitest
|
||||
# git push private cloud/integration # plain fast-forward push; if rejected, rerun (someone merged)
|
||||
set -euo pipefail
|
||||
|
||||
PRIVATE_BRANCHES=(${PRIVATE_BRANCHES:-nwparker/accounts-billing nwparker/vercel-driver})
|
||||
@@ -26,22 +26,18 @@ git config rerere.autoupdate true
|
||||
git fetch -q origin main
|
||||
for b in "${STACKED[@]}"; do git fetch -q origin "+$b:refs/remotes/origin/$b"; done
|
||||
for b in "${PRIVATE_BRANCHES[@]}"; do git fetch -q private "+$b:refs/remotes/private/$b"; done
|
||||
git fetch -q private +cloud/integration:refs/remotes/private/cloud/integration 2>/dev/null || true
|
||||
git fetch -q private +cloud/integration:refs/remotes/private/cloud/integration
|
||||
|
||||
[[ "${1:-}" == --resume ]] || git checkout -q -B cloud/integration-next origin/main
|
||||
if [[ -n "$(git status --porcelain --untracked-files=no)" ]]; then
|
||||
echo "Working tree has changes; commit or set them aside first." >&2; exit 1
|
||||
fi
|
||||
git checkout -q -B cloud/integration private/cloud/integration
|
||||
|
||||
for ref in "${PRIVATE_BRANCHES[@]/#/private/}" "${STACKED[@]/#/origin/}"; do
|
||||
for ref in origin/main "${PRIVATE_BRANCHES[@]/#/private/}" "${STACKED[@]/#/origin/}"; do
|
||||
git merge-base --is-ancestor "$ref" HEAD && continue
|
||||
git merge --no-ff --no-edit "$ref" || {
|
||||
echo "Conflict merging $ref. Resolve (policy above), git add -A && git commit --no-edit, rerun with --resume." >&2
|
||||
git merge --no-ff --no-edit -m "Merge $ref into cloud/integration" "$ref" || {
|
||||
echo "Conflict merging $ref. Resolve (policy above), git add -A && git commit --no-edit, rerun." >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
if git rev-parse -q --verify private/cloud/integration >/dev/null; then
|
||||
for c in $(git log --reverse --no-merges --format=%H --grep='^chore(cloud-integration)' origin/main..private/cloud/integration); do
|
||||
git log --format=%s origin/main..HEAD | grep -qxF "$(git log -1 --format=%s "$c")" && continue
|
||||
git cherry-pick "$c" || { echo "Conflict re-applying $c; resolve, git cherry-pick --continue, rerun with --resume." >&2; exit 1; }
|
||||
done
|
||||
fi
|
||||
echo "cloud/integration-next ready at $(git rev-parse --short HEAD) on stablyai/orca main $(git rev-parse --short origin/main)."
|
||||
echo "cloud/integration at $(git rev-parse --short HEAD), $(git rev-list --count private/cloud/integration..HEAD) new commit(s) over private. Verify, then: git push private cloud/integration"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { withCloudBuildDefaults } from './cloud-build-defaults'
|
||||
import { cloudDevSigningAllowed, withCloudBuildDefaults } from './cloud-build-defaults'
|
||||
|
||||
describe('withCloudBuildDefaults', () => {
|
||||
afterEach(() => vi.unstubAllGlobals())
|
||||
@@ -23,4 +23,11 @@ describe('withCloudBuildDefaults', () => {
|
||||
ORCA_CLOUD_SANDBOX_URL: 'https://override.example'
|
||||
})
|
||||
})
|
||||
|
||||
it('allows dev signing in packaged builds only when the build opts in', () => {
|
||||
expect(cloudDevSigningAllowed(false)).toBe(true)
|
||||
expect(cloudDevSigningAllowed(true)).toBe(false)
|
||||
vi.stubGlobal('ORCA_CLOUD_BUILD_DEFAULTS', { allowDevSigning: true })
|
||||
expect(cloudDevSigningAllowed(true)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
// Packaged builds read no shell env, so the integration build bakes in its backend URLs
|
||||
// (config/cloud-build-defaults.json via electron.vite.config.ts). Run-time env still wins.
|
||||
declare const ORCA_CLOUD_BUILD_DEFAULTS: { billingApiUrl?: string; cloudSandboxUrl?: string } | null
|
||||
declare const ORCA_CLOUD_BUILD_DEFAULTS: {
|
||||
billingApiUrl?: string
|
||||
cloudSandboxUrl?: string
|
||||
allowDevSigning?: boolean
|
||||
} | null
|
||||
|
||||
function buildDefaults(): { billingApiUrl?: string; cloudSandboxUrl?: string } {
|
||||
function buildDefaults(): {
|
||||
billingApiUrl?: string
|
||||
cloudSandboxUrl?: string
|
||||
allowDevSigning?: boolean
|
||||
} {
|
||||
// oxlint-disable-next-line unicorn/no-typeof-undefined -- undeclared outside electron-vite builds; a bare read throws.
|
||||
return (typeof ORCA_CLOUD_BUILD_DEFAULTS === 'undefined' ? null : ORCA_CLOUD_BUILD_DEFAULTS) ?? {}
|
||||
}
|
||||
@@ -15,3 +23,8 @@ export function withCloudBuildDefaults(env: NodeJS.ProcessEnv): NodeJS.ProcessEn
|
||||
ORCA_CLOUD_SANDBOX_URL: env.ORCA_CLOUD_SANDBOX_URL?.trim() || defaults.cloudSandboxUrl
|
||||
}
|
||||
}
|
||||
|
||||
/** Dev-key sandbox signing: always in unpackaged runs; in packaged builds only when the integration build opts in. */
|
||||
export function cloudDevSigningAllowed(packaged: boolean): boolean {
|
||||
return !packaged || buildDefaults().allowDevSigning === true
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { createPrivateKey, sign } from 'node:crypto'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { z } from 'zod'
|
||||
import { cloudDevSigningAllowed } from '../cloud-build-defaults'
|
||||
import { cleanCloudServiceUrl } from '../../shared/cloud-service-url'
|
||||
import { getOrcaCloudAuthConfig } from '../orca-profiles/profile-cloud-auth-config'
|
||||
import { OrcaCloudRequestError } from '../orca-profiles/profile-cloud-client'
|
||||
@@ -42,7 +43,9 @@ export function getHostedSandboxConfig(
|
||||
if (!controlPlaneUrl) {
|
||||
return null
|
||||
}
|
||||
const devKeyFile = packaged ? undefined : env.ORCA_CLOUD_SANDBOX_DEV_KEY_FILE?.trim()
|
||||
const devKeyFile = cloudDevSigningAllowed(packaged)
|
||||
? env.ORCA_CLOUD_SANDBOX_DEV_KEY_FILE?.trim()
|
||||
: undefined
|
||||
let cached: { token: string; expiresAt: number } | null = null
|
||||
return {
|
||||
controlPlaneUrl,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { withCloudBuildDefaults } from '../cloud-build-defaults'
|
||||
import { cloudDevSigningAllowed, withCloudBuildDefaults } from '../cloud-build-defaults'
|
||||
// Wires Orca Cloud into the desktop when this build has a control plane configured (off by default).
|
||||
import { app, BrowserWindow } from 'electron'
|
||||
import { ensureActiveOrcaProfile } from '../orca-profiles/profile-index-store'
|
||||
@@ -72,7 +72,7 @@ export function installHostedSandbox(): void {
|
||||
|
||||
/** Orca Cloud auth's `sandbox` capability rolls it out per account; the dev key bypasses it in dev builds. */
|
||||
async function orcaCloudOffered(): Promise<boolean> {
|
||||
if (!app.isPackaged && process.env.ORCA_CLOUD_SANDBOX_DEV_KEY_FILE) {
|
||||
if (cloudDevSigningAllowed(app.isPackaged) && process.env.ORCA_CLOUD_SANDBOX_DEV_KEY_FILE) {
|
||||
return true
|
||||
}
|
||||
const auth = getOrcaCloudAuthConfig(process.env, app.isPackaged)
|
||||
|
||||
Reference in New Issue
Block a user