Skip to content

Commit f82384f

Browse files
committed
Unify installation process
1 parent d060747 commit f82384f

10 files changed

Lines changed: 1956 additions & 2282 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Refresh Shared Template
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: refresh-shared-template-${{ github.ref }}
10+
cancel-in-progress: false
11+
12+
jobs:
13+
refresh-opengauss-template:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
env:
18+
DEVBOX_TEMPLATE_BASE_URL: https://devbox.svc.cloud.morph.so
19+
TEMPLATE_ALIAS: opengauss
20+
MORPH_API_KEY: ${{ secrets.MORPH_API_KEY }}
21+
steps:
22+
- name: Validate refresh credentials
23+
run: |
24+
if [ -z "${MORPH_API_KEY}" ]; then
25+
echo "GitHub secret MORPH_API_KEY is required to refresh the shared template alias." >&2
26+
exit 1
27+
fi
28+
29+
- name: Refresh shared template alias
30+
run: |
31+
python3 - <<'PY'
32+
import json
33+
import os
34+
import sys
35+
import urllib.request
36+
37+
base = os.environ["DEVBOX_TEMPLATE_BASE_URL"].rstrip("/")
38+
key = os.environ["MORPH_API_KEY"]
39+
alias = os.environ["TEMPLATE_ALIAS"]
40+
41+
body = {
42+
"description": f"Automatic refresh from {os.environ.get('GITHUB_REPOSITORY', 'repo')}@{os.environ.get('GITHUB_SHA', '')[:12]}"
43+
}
44+
45+
req = urllib.request.Request(
46+
f"{base}/api/templates/aliases/{alias}/refresh",
47+
data=json.dumps(body).encode("utf-8"),
48+
headers={
49+
"Authorization": f"Bearer {key}",
50+
"Content-Type": "application/json",
51+
},
52+
method="POST",
53+
)
54+
55+
with urllib.request.urlopen(req, timeout=120) as resp:
56+
started = json.load(resp)
57+
58+
print("refresh_started", json.dumps(started))
59+
60+
events_path = started.get("events_path")
61+
if not events_path:
62+
sys.exit("refresh response did not include events_path")
63+
64+
events_req = urllib.request.Request(
65+
f"{base}{events_path}",
66+
headers={"Authorization": f"Bearer {key}"},
67+
method="GET",
68+
)
69+
70+
completed = None
71+
saw_force_rebuild = False
72+
with urllib.request.urlopen(events_req, timeout=3600) as resp:
73+
for raw in resp:
74+
line = raw.decode("utf-8", errors="replace").strip()
75+
if not line.startswith("data: "):
76+
continue
77+
event = json.loads(line[6:])
78+
print(json.dumps(event))
79+
if event.get("type") == "force_rebuild":
80+
saw_force_rebuild = True
81+
if event.get("type") in {"completed", "error", "cancelled"}:
82+
completed = event
83+
break
84+
85+
if not completed:
86+
sys.exit("refresh events stream ended without a terminal event")
87+
if completed.get("type") != "completed":
88+
sys.exit(f"refresh failed: {completed}")
89+
if not saw_force_rebuild:
90+
sys.exit("refresh completed without force_rebuild event")
91+
92+
alias_publish = completed.get("aliasPublish") or {}
93+
if not alias_publish.get("published"):
94+
sys.exit(f"alias was not promoted: {alias_publish}")
95+
96+
print("alias_promoted_to", alias_publish.get("templateId"))
97+
PY

README.md

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Each lifted slash command spawns a managed backend child agent in the active pro
2020

2121
## Install
2222

23+
If you want the fastest path, `https://morph.new/opengauss` launches the hosted setup in under 10 seconds. The local installers below are the batteries-included path for your own machine and can take up to 10 minutes.
24+
2325
### macOS and Linux
2426

2527
```bash
@@ -28,36 +30,58 @@ cd OpenGauss
2830
./scripts/install.sh
2931
```
3032

31-
The installer will:
33+
This is the canonical local install path. It bootstraps the local installer runtime, runs the shared `opengauss` installer flow on your machine, and then auto-attaches to the final `gauss` tmux session when possible.
34+
35+
It will:
3236

33-
1. Install system dependencies (via Homebrew on macOS, apt on Ubuntu/Debian)
34-
2. Install `uv`, Node.js, Claude Code, and the Lean toolchain if missing
35-
3. Create a Python virtualenv and install Gauss
36-
4. Link the `gauss` command to `~/.local/bin/gauss`
37-
5. Set up `~/.gauss/` for runtime config and secrets
38-
6. Auto-configure the main provider/model from staged keys when possible
37+
1. Install `uv` if needed
38+
2. Create a repo-local installer environment
39+
3. Install or upgrade the local runner
40+
4. Run the shared `opengauss` installer flow on your machine
41+
5. Auto-attach you to the local `gauss` tmux session when possible, or print the exact `tmux attach -t gauss` command if not
3942

40-
`~/.local/bin/gauss` is ready immediately after install. To use plain `gauss` in the same terminal, reload your shell first:
43+
You can pass normal template-runner flags through to the alternate script, for example:
4144

4245
```bash
43-
source ~/.bashrc # bash
44-
source ~/.zshrc # zsh
45-
gauss
46+
./scripts/install.sh --plain
47+
./scripts/install.sh --secret OPENAI_API_KEY=...
48+
./scripts/install.sh --secret ANTHROPIC_API_KEY=...
4649
```
4750

48-
Run `gauss setup` later if you want to review or change the selected provider, model, or other settings.
51+
### Windows (via WSL2)
4952

50-
If you prefer Gauss to create a prewarmed Lean workspace during install:
53+
Open Gauss on Windows runs through WSL2 using the same shared installer flow.
5154

52-
```bash
53-
./scripts/install.sh --with-workspace
55+
From PowerShell:
56+
57+
```powershell
58+
.\scripts\install.ps1 -WithWorkspace
5459
```
5560

56-
Otherwise, after install just start Gauss:
61+
This bootstrap:
62+
63+
1. Starts your WSL distro
64+
2. Clones or updates `OpenGauss` inside your WSL home directory
65+
3. Runs `./scripts/install.sh` there, which executes the shared `opengauss` installer flow inside WSL
66+
67+
If no WSL distro is initialized yet, the bootstrap will install Ubuntu for you with `wsl --install -d Ubuntu`. If that process drops you into the new Linux shell, type `exit` to return to PowerShell and rerun `.\scripts\install.ps1 -WithWorkspace`. Windows may also ask to enable WSL features or restart before you rerun the installer.
68+
69+
If WSL is not installed yet:
70+
71+
```powershell
72+
wsl --install -d Ubuntu
73+
```
74+
75+
You can also install manually inside WSL:
5776

5877
```bash
59-
gauss
78+
wsl
79+
git clone https://github.com/math-inc/OpenGauss.git ~/OpenGauss
80+
cd ~/OpenGauss
81+
./scripts/install.sh
6082
```
83+
84+
Use a Linux path such as `~/OpenGauss`, not `/mnt/c/...`, for the best performance and terminal behavior.
6185
## Configuration
6286

6387
### 🖥️ Using Local Models (vLLM)
@@ -67,15 +91,8 @@ If you prefer to run models locally (e.g., using a local GPU) to save on API cos
6791
```bash
6892
python -m vllm.entrypoints.openai.api_server --model <model_name>
6993
```
70-
2. **Point Gauss at that server** with `gauss setup`, or update `OPENAI_BASE_URL` in `~/.gauss/.env`.
7194

72-
### Options
73-
74-
```bash
75-
./scripts/install.sh --with-workspace # Also create a prewarmed Lean+Mathlib workspace (~2 GB download)
76-
./scripts/install.sh --skip-system-packages # Skip Homebrew/apt package installation
77-
./scripts/install.sh --recreate-venv # Force-recreate the Python virtualenv
78-
```
95+
2. **Point Gauss at that server** with `gauss setup`, or update `OPENAI_BASE_URL` in `~/.gauss/.env`.
7996

8097
### Updating
8198

gauss_cli/setup.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,10 +2492,17 @@ def run_setup_wizard(args):
24922492
from gauss_cli.auth import get_active_provider
24932493

24942494
active_provider = get_active_provider()
2495+
force_first_time = (
2496+
str(getattr(args, "force_first_time", "") or "").strip().lower() in {"1", "true", "yes", "on"}
2497+
or os.getenv("GAUSS_FORCE_FIRST_TIME_SETUP", "").strip().lower() in {"1", "true", "yes", "on"}
2498+
)
24952499
is_existing = (
2496-
bool(get_env_value("OPENROUTER_API_KEY"))
2497-
or bool(get_env_value("OPENAI_BASE_URL"))
2498-
or active_provider is not None
2500+
not force_first_time
2501+
and (
2502+
bool(get_env_value("OPENROUTER_API_KEY"))
2503+
or bool(get_env_value("OPENAI_BASE_URL"))
2504+
or active_provider is not None
2505+
)
24992506
)
25002507

25012508
print()

0 commit comments

Comments
 (0)