feat: vercel deploy status in ecosystem bar, deploy rule in CLAUDE.md
This commit is contained in:
parent
90ac87db41
commit
f5817eb156
|
|
@ -33,6 +33,15 @@ npm run deploy # = git push gitea main && git push github main
|
|||
**VPS バックエンド(server.js)のデプロイ:**
|
||||
`bash deploy-server.sh` を実行する(完全無人。手動で `scp` しない)。
|
||||
|
||||
**posimai-dev(Ubuntu PC サービス)のデプロイ:**
|
||||
`posimai-dev/` 以下のファイルを変更したら、必ず以下を実行すること。
|
||||
|
||||
```bash
|
||||
npm run deploy:dev # = git push + scp転送 + systemctl restart posimai-dev
|
||||
```
|
||||
|
||||
`git push` だけでは Ubuntu PC に反映されない(Syncthing の同期遅延があるため)。
|
||||
|
||||
## 3. アプリ追加・更新時の必須タスク(ダッシュボード追記)
|
||||
|
||||
エコシステムからの孤立を防ぐため、新規アプリ作成や既存アプリ修正の際は**必ずユーザーに言われる前に**ダッシュボードのリポジトリを更新しデプロイすること。
|
||||
|
|
|
|||
|
|
@ -180,6 +180,28 @@ app.get('/api/gitea-commit', async (req, res) => {
|
|||
} catch (e) { res.json({ error: e.message }); }
|
||||
});
|
||||
|
||||
// ── Vercel 最新デプロイ (/api/vercel-deploys) ──────────────────
|
||||
app.get('/api/vercel-deploys', async (req, res) => {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
const token = process.env.VERCEL_TOKEN || '';
|
||||
if (!token) return res.status(503).json({ error: 'no token' });
|
||||
try {
|
||||
const r = await fetch('https://api.vercel.com/v6/deployments?limit=1', {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
signal: AbortSignal.timeout(6000),
|
||||
});
|
||||
const data = await r.json();
|
||||
const d = data.deployments?.[0];
|
||||
if (!d) return res.json({ error: 'no deployments' });
|
||||
res.json({
|
||||
name: d.name,
|
||||
state: d.state,
|
||||
url: d.url,
|
||||
created: d.createdAt,
|
||||
});
|
||||
} catch (e) { res.status(502).json({ error: e.message }); }
|
||||
});
|
||||
|
||||
// ── VPS health プロキシ (/api/vps-health) ──────────────────────
|
||||
// ブラウザから直接叩くと自己署名証明書環境でCORSエラーになるためサーバー経由でプロキシ
|
||||
app.get('/api/vps-health', async (req, res) => {
|
||||
|
|
|
|||
|
|
@ -325,6 +325,8 @@
|
|||
<div id="ecosystem-bar">
|
||||
<div class="eco-item"><div class="eco-dot" id="eco-gitea-dot"></div><span id="eco-commit">commit: —</span></div>
|
||||
<div class="eco-item" style="color:var(--border);font-size:8px">|</div>
|
||||
<div class="eco-item"><div class="eco-dot" id="eco-vercel-dot"></div><span id="eco-vercel">deploy: —</span></div>
|
||||
<div class="eco-item" style="color:var(--border);font-size:8px">|</div>
|
||||
<div class="eco-item" id="eco-temp-item" style="display:none"><span id="eco-temp-label">temp: —</span></div>
|
||||
</div>
|
||||
<div id="bottom-row">
|
||||
|
|
@ -705,6 +707,25 @@ function timeAgo(iso){
|
|||
fetchGiteaCommit();
|
||||
setInterval(fetchGiteaCommit, 120000);
|
||||
|
||||
// ── Vercel 最新デプロイ ─────────────────────────────────────────
|
||||
async function fetchVercelDeploy(){
|
||||
try{
|
||||
const r=await fetch('/api/vercel-deploys',{signal:AbortSignal.timeout(8000)});
|
||||
const d=await r.json();
|
||||
if(d.error) return;
|
||||
const dot=document.getElementById('eco-vercel-dot');
|
||||
const el=document.getElementById('eco-vercel');
|
||||
const stateMap={READY:'var(--ok)',ERROR:'var(--crit)',BUILDING:'var(--warn)',CANCELED:'var(--text3)'};
|
||||
const color=stateMap[d.state]||'var(--text3)';
|
||||
if(dot) dot.style.background=color;
|
||||
const ago=timeAgo(d.created);
|
||||
const label=(d.name||'').replace(/^posimai-/,'');
|
||||
if(el) el.textContent=`deploy: ${label} ${d.state?.toLowerCase()} ${ago}`;
|
||||
}catch(_){}
|
||||
}
|
||||
fetchVercelDeploy();
|
||||
setInterval(fetchVercelDeploy, 300000);
|
||||
|
||||
// ── VPS メトリクス ─────────────────────────────────────────────
|
||||
async function fetchVpsHealth(){
|
||||
try{
|
||||
|
|
|
|||
Loading…
Reference in New Issue