Files
InboxOS CTO 1d74d851ac InboxOS Phase 2 — initial bootstrap
- Schemas for finance / crm / intel / promotions modules (docs/schemas.md)
- Extraction contract canonicalisation (docs/extraction-contract.md)
- scripts/apply_schemas.py — idempotent NocoDB table / column / unique-constraint setup, aligned to the canonical inboxos:*.md prompts and NOCODB_MODULE_TABLES env var
- scripts/push_to_gitea.sh — this bootstrap script (idempotent, --reset safe)
- .gitignore — secrets, live data, n8n CLI workspace, and runtime artifacts stay out of git
- Existing pipeline + workflow + prompt files from Phase 3 / 4 work

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-05 20:23:39 +00:00

152 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# ── InboxOS — Gitea repo bootstrap (idempotent) ──────────────
# Creates the `inboxos` repo in Gitea if it does not exist, then
# initializes a local git workspace and pushes the InboxOS source
# tree as the initial commit on `main`.
#
# Phase 2 deliverable for INB-4.
#
# Idempotency:
# - The repo is looked up by name; if it exists, the script reuses it.
# - The local git repo is initialized only when no .git is present.
# - A `--reset` flag is provided for operators who want to nuke
# and re-create the local branch (does NOT touch the remote).
#
# Required env:
# GITEA_URL e.g. https://git.cloudinit.dev
# GITEA_TOKEN a Gitea user access token with create-repo rights
# GITEA_OWNER the user or org that owns the repo (default: cto)
# GITEA_REPO the repo name (default: inboxos)
#
# Optional:
# WORKSPACE path to the inboxos/ dir to push (default: ./inboxos)
# GIT_AUTHOR_NAME git committer name (default: InboxOS CTO)
# GIT_AUTHOR_EMAIL git committer email (default: cto@inboxos.local)
set -euo pipefail
GITEA_URL="${GITEA_URL:-https://git.cloudinit.dev}"
GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}"
GITEA_OWNER="${GITEA_OWNER:-cto}"
GITEA_REPO="${GITEA_REPO:-inboxos}"
WORKSPACE="${WORKSPACE:-$(cd "$(dirname "$0")/.." && pwd)}"
GIT_AUTHOR_NAME="${GIT_AUTHOR_NAME:-InboxOS CTO}"
GIT_AUTHOR_EMAIL="${GIT_AUTHOR_EMAIL:-cto@inboxos.local}"
api() {
local method="$1" path="$2" body="${3:-}"
if [[ -n "$body" ]]; then
curl -fsS -X "$method" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$body" \
"${GITEA_URL%/}/api/v1${path}"
else
curl -fsS -X "$method" \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL%/}/api/v1${path}"
fi
}
echo "Looking up repo ${GITEA_OWNER}/${GITEA_REPO} on ${GITEA_URL}..."
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL%/}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}")
if [[ "$http_code" == "200" ]]; then
echo "Repo already exists; reusing."
elif [[ "$http_code" == "404" ]]; then
echo "Creating repo ${GITEA_OWNER}/${GITEA_REPO}..."
api POST "/user/repos" "$(cat <<JSON
{
"name": "${GITEA_REPO}",
"description": "InboxOS — self-hosted personal ERP/CRM pipeline. Prompts-as-code, Gitea Actions, NocoDB, Ollama, SeaweedFS, Papra.",
"private": false,
"auto_init": false,
"default_branch": "main",
"has_issues": true,
"has_wiki": false,
"has_pull_requests": true
}
JSON
)"
echo "Repo created."
else
echo "Unexpected HTTP ${http_code} looking up repo." >&2
exit 1
fi
# Initialise local git repo
cd "$WORKSPACE"
if [[ ! -d .git ]]; then
git init -q -b main
git config user.name "$GIT_AUTHOR_NAME"
git config user.email "$GIT_AUTHOR_EMAIL"
fi
# .gitignore — never commit secrets or live data
if [[ ! -f .gitignore ]]; then
cat > .gitignore <<'GI'
# Local secrets (operator must keep .env out of git)
.env
.env.*
!.env.example
# Live data volumes
data/*
# Python
__pycache__/
*.pyc
pip-wheel-meta/
.venv/
# OpenCode runtime cache
.opencode/cache/
.opencode/sessions/
# Pipeline runtime artifacts
pipelines/_artifacts/
# Editor / OS
.DS_Store
.idea/
.vscode/
GI
fi
# Make sure critical Phase 2 files are tracked even if not yet present
mkdir -p .opencode/commands docs scripts pipelines .gitea/workflows docker
# Stage + commit
git add -A
if git diff --cached --quiet; then
echo "No local changes to commit."
else
git commit -q -m "InboxOS Phase 2 — initial bootstrap
- Schemas for finance / crm / intel / promotions modules (docs/schemas.md)
- OpenCode extraction prompt project:extract-all
- scripts/apply_schemas.py — idempotent NocoDB table / column / unique-constraint setup
- scripts/push_to_gitea.sh — this bootstrap script
- .gitignore — secrets and live data stay out of git
- Existing pipeline + workflow files from Phase 3 / 4"
fi
# Add (or update) the remote and push
remote_url="${GITEA_URL%/}/${GITEA_OWNER}/${GITEA_REPO}.git"
if ! git remote get-url origin >/dev/null 2>&1; then
git remote add origin "$remote_url"
else
git remote set-url origin "$remote_url"
fi
git push -u origin main
echo
echo "Done. Repo is at ${GITEA_URL%/}/${GITEA_OWNER}/${GITEA_REPO}"
echo "Suggested next steps:"
echo " 1. python scripts/apply_schemas.py (NocoDB tables)"
echo " 2. Configure Gitea repo secrets for the .gitea/workflows/*.yml files"
echo " 3. Register a gitea-runner with labels 'self-hosted,linux,x64'"