230 lines
8.4 KiB
Bash
230 lines
8.4 KiB
Bash
#!/usr/bin/env bash
|
||
# ============================================
|
||
# Posimai — 新規アプリ作成スクリプト
|
||
# 使い方: bash create-app.sh posimai-myapp "My App Name" "アプリの説明"
|
||
# ============================================
|
||
set -e
|
||
|
||
APP_ID="${1}"
|
||
APP_NAME="${2}"
|
||
APP_DESC="${3:-${APP_NAME}}"
|
||
|
||
# --- 引数チェック ---
|
||
if [ -z "$APP_ID" ] || [ -z "$APP_NAME" ]; then
|
||
echo "使い方: bash create-app.sh <app-id> <app-name> [description]"
|
||
echo "例: bash create-app.sh posimai-memo \"Posimai Memo\" \"メモ帳\""
|
||
exit 1
|
||
fi
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
TARGET_DIR="$SCRIPT_DIR/$APP_ID"
|
||
|
||
if [ -d "$TARGET_DIR" ]; then
|
||
echo "[ERROR] ディレクトリが既に存在します: $TARGET_DIR"
|
||
exit 1
|
||
fi
|
||
|
||
GITEA_BASE="http://100.76.7.3:3000/mai"
|
||
GITHUB_ORG="posimai"
|
||
|
||
echo "========================================"
|
||
echo " Posimai App Creator"
|
||
echo "========================================"
|
||
echo " APP_ID : $APP_ID"
|
||
echo " APP_NAME: $APP_NAME"
|
||
echo " APP_DESC: $APP_DESC"
|
||
echo "========================================"
|
||
echo ""
|
||
|
||
# --- Step 1: テンプレートコピー & 置換 ---
|
||
echo "Step 1: テンプレートをコピーして置換..."
|
||
cp -r "$SCRIPT_DIR/_template-minimal" "$TARGET_DIR"
|
||
|
||
# sed で 3 変数を一括置換(macOS / Linux / Git Bash 対応)
|
||
find "$TARGET_DIR" -type f \( -name "*.html" -o -name "*.json" -o -name "*.js" -o -name "*.md" \) | while IFS= read -r f; do
|
||
sed -i "s/APP_NAME/$APP_NAME/g; s/APP_ID/$APP_ID/g; s/APP_DESCRIPTION/$APP_DESC/g" "$f"
|
||
done
|
||
|
||
echo " コピー完了: $TARGET_DIR"
|
||
|
||
# --- Step 2: Git 初期化 ---
|
||
echo ""
|
||
echo "Step 2: Git 初期化..."
|
||
cd "$TARGET_DIR"
|
||
git init -b main
|
||
git add .
|
||
git commit -m "init: $APP_NAME"
|
||
echo " Git 初期化完了"
|
||
|
||
# --- Step 3: Gitea にリポジトリ作成 ---
|
||
echo ""
|
||
echo "Step 3: Gitea にリポジトリを作成..."
|
||
|
||
# git credential store から認証情報を取得
|
||
GITEA_PASS=$(git credential fill <<< $'protocol=http\nhost=100.76.7.3:3000' | grep password | cut -d= -f2)
|
||
if [ -z "$GITEA_PASS" ]; then
|
||
echo "[ERROR] Gitea credential が取得できませんでした。git credential store を確認してください。"
|
||
exit 1
|
||
fi
|
||
GITEA_RESP=$(curl -s -X POST "http://100.76.7.3:3000/api/v1/user/repos" \
|
||
-H "Content-Type: application/json" \
|
||
-u "mai:$GITEA_PASS" \
|
||
-d "{\"name\":\"$APP_ID\",\"private\":false,\"auto_init\":false}")
|
||
if echo "$GITEA_RESP" | grep -q '"full_name"'; then
|
||
echo " Gitea リポジトリ作成完了"
|
||
elif echo "$GITEA_RESP" | grep -q 'same name already exists'; then
|
||
echo " Gitea リポジトリは既存。push のみ実行します。"
|
||
else
|
||
echo " [WARN] Gitea 応答: $GITEA_RESP"
|
||
fi
|
||
|
||
# --- Step 4: GitHub にリポジトリ作成 ---
|
||
echo ""
|
||
echo "Step 4: GitHub にリポジトリを作成..."
|
||
gh repo create "$GITHUB_ORG/$APP_ID" --private --description "$APP_DESC" 2>&1 || {
|
||
echo " [WARN] GitHub リポジトリ作成に失敗(既存の可能性)。続行します。"
|
||
}
|
||
echo " GitHub リポジトリ作成完了"
|
||
|
||
# --- Step 5: リモート追加 & push ---
|
||
echo ""
|
||
echo "Step 5: リモートを追加して push..."
|
||
git remote add gitea "$GITEA_BASE/$APP_ID.git"
|
||
git remote add github "https://github.com/$GITHUB_ORG/$APP_ID.git"
|
||
npm run deploy
|
||
echo " push 完了"
|
||
|
||
# --- Step 6: Vercel 連携 ---
|
||
echo ""
|
||
echo "Step 6: Vercel と GitHub を連携..."
|
||
echo "https://github.com/$GITHUB_ORG/$APP_ID.git" | vercel git connect 2>&1 || {
|
||
echo " [WARN] vercel git connect に失敗。手動で連携してください。"
|
||
}
|
||
|
||
# --- Step 7: 初回本番デプロイ ---
|
||
echo ""
|
||
echo "Step 7: 初回本番デプロイをトリガー..."
|
||
git commit --allow-empty -m "ci: trigger initial Vercel deployment"
|
||
npm run deploy
|
||
|
||
# --- Step 7.5: カスタムドメイン設定 ---
|
||
echo ""
|
||
echo "Step 7.5: カスタムドメイン設定..."
|
||
SUBDOMAIN="${APP_ID#posimai-}"
|
||
CUSTOM_DOMAIN="${SUBDOMAIN}.posimai.soar-enrich.com"
|
||
cd "$TARGET_DIR"
|
||
vercel domains add "$CUSTOM_DOMAIN" 2>&1 || true
|
||
echo " デプロイ完了を15秒待機中..."
|
||
sleep 15
|
||
DEPLOY_URL=$(vercel ls 2>&1 | grep "Ready" | head -1 | awk '{print $2}')
|
||
if [ -n "$DEPLOY_URL" ]; then
|
||
vercel alias set "$DEPLOY_URL" "$CUSTOM_DOMAIN" \
|
||
&& echo " カスタムドメイン割り当て完了: https://$CUSTOM_DOMAIN" \
|
||
|| echo " [WARN] alias set 失敗。後で手動実行: vercel alias set $DEPLOY_URL $CUSTOM_DOMAIN"
|
||
else
|
||
echo " [WARN] デプロイ URL 未取得。後で手動実行: vercel alias set <URL> $CUSTOM_DOMAIN"
|
||
fi
|
||
|
||
# --- Step 8: Dashboard 自動更新 ---
|
||
echo ""
|
||
echo "Step 8: Dashboard を自動更新..."
|
||
|
||
DASHBOARD_DIR="$SCRIPT_DIR/posimai-dashboard"
|
||
ROADMAP_DIR="$SCRIPT_DIR/posimai-roadmap"
|
||
TODAY=$(date +%Y-%m-%d)
|
||
|
||
# projects.json に追加
|
||
node -e "
|
||
const fs = require('fs');
|
||
const f = '$DASHBOARD_DIR/src/data/projects.json';
|
||
const d = JSON.parse(fs.readFileSync(f, 'utf8'));
|
||
const already = d.projects.some(p => p.id === '$APP_ID');
|
||
if (!already) {
|
||
d.projects.unshift({
|
||
id: '$APP_ID',
|
||
name: '$APP_NAME',
|
||
category: 'micro',
|
||
status: 'beta',
|
||
description: '$APP_DESC',
|
||
techStack: ['HTML', 'CSS', 'JavaScript', 'PWA'],
|
||
links: { github: 'https://github.com/$GITHUB_ORG/$APP_ID' },
|
||
pwa: true,
|
||
themeColor: '#0D0D0D',
|
||
accentColor: '#6EE7B7'
|
||
});
|
||
d.lastUpdated = '$TODAY';
|
||
fs.writeFileSync(f, JSON.stringify(d, null, 4));
|
||
console.log(' projects.json: 追加完了');
|
||
} else {
|
||
console.log(' projects.json: 既存エントリあり、スキップ');
|
||
}
|
||
" || echo " [WARN] projects.json の更新に失敗しました"
|
||
|
||
# timeline/page.tsx に launch エントリを追加
|
||
TIMELINE_FILE="$DASHBOARD_DIR/src/app/timeline/page.tsx"
|
||
if grep -q "\"$APP_ID\"" "$TIMELINE_FILE" 2>/dev/null; then
|
||
echo " timeline/page.tsx: 既存エントリあり、スキップ"
|
||
else
|
||
# "const EVENTS: TimelineEvent[] = [" の直後に挿入
|
||
sed -i "s/const EVENTS: TimelineEvent\[\] = \[/const EVENTS: TimelineEvent[] = [\n { date: \"$TODAY\", type: \"launch\", app: \"$APP_ID\", title: \"$APP_NAME リリース\", desc: \"$APP_DESC\" },/" \
|
||
"$TIMELINE_FILE" \
|
||
&& echo " timeline/page.tsx: 追加完了" \
|
||
|| echo " [WARN] timeline/page.tsx の更新に失敗しました"
|
||
fi
|
||
|
||
# roadmap.json に追加
|
||
node -e "
|
||
const fs = require('fs');
|
||
const f = '$ROADMAP_DIR/roadmap.json';
|
||
const d = JSON.parse(fs.readFileSync(f, 'utf8'));
|
||
if (!d.apps) d.apps = [];
|
||
const already = d.apps.some(a => a.id === '$APP_ID');
|
||
if (!already) {
|
||
d.apps.push({ id: '$APP_ID', tasks: [] });
|
||
fs.writeFileSync(f, JSON.stringify(d, null, 2));
|
||
console.log(' roadmap.json: 追加完了');
|
||
} else {
|
||
console.log(' roadmap.json: 既存エントリあり、スキップ');
|
||
}
|
||
" || echo " [WARN] roadmap.json の更新に失敗しました"
|
||
|
||
# Dashboard と Roadmap をデプロイ
|
||
echo ""
|
||
echo " Dashboard をデプロイ中..."
|
||
cd "$DASHBOARD_DIR"
|
||
git add src/data/projects.json src/app/timeline/page.tsx && \
|
||
git commit -m "feat: $APP_NAME をダッシュボードに追加" && \
|
||
npm run deploy && \
|
||
echo " Dashboard デプロイ完了" || echo " [WARN] Dashboard デプロイに失敗しました"
|
||
|
||
echo ""
|
||
echo " Roadmap をデプロイ中..."
|
||
cd "$ROADMAP_DIR"
|
||
git add roadmap.json && \
|
||
git commit -m "feat: $APP_NAME を roadmap に追加" && \
|
||
npm run deploy && \
|
||
echo " Roadmap デプロイ完了" || echo " [WARN] Roadmap デプロイに失敗しました"
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
echo " 完了! $APP_NAME"
|
||
echo "========================================"
|
||
echo ""
|
||
echo " ディレクトリ : $TARGET_DIR"
|
||
echo " Gitea : http://100.76.7.3:3000/mai/$APP_ID"
|
||
echo " GitHub : https://github.com/$GITHUB_ORG/$APP_ID"
|
||
echo " 本番 URL : https://${APP_ID#posimai-}.posimai.soar-enrich.com"
|
||
echo ""
|
||
echo " 自動完了済み:"
|
||
echo " - projects.json にカード追加"
|
||
echo " - timeline/page.tsx に launch エントリ追加"
|
||
echo " - roadmap.json に追加"
|
||
echo " - Dashboard / Roadmap デプロイ"
|
||
echo " - カスタムドメイン設定 (vercel domains add + alias set)"
|
||
echo ""
|
||
echo " 手動で追加が必要なもの:"
|
||
echo " 1. apps/page.tsx の projectIds に追加(カテゴリ判断が必要)"
|
||
echo " 2. ecosystem/page.tsx の NODES / EDGES に追加(接続関係の判断が必要)"
|
||
echo " 3. logo.png を配置後: cd $TARGET_DIR && git add logo.png && git commit -m 'feat: logo 追加' && npm run deploy"
|
||
echo ""
|