사이트 인터랙티브 워크스테이션 확장 + 감사 폴리시 재적용 + 원클릭 릴리스 도구 — 병행 세션 확장분(히어로 3탭 워크스테이션 시뮬레이터, 비교 섹션(기존 방식 vs MEDIABROWSER), 가이드 단축키 섹션(kbd), 스포트라이트 카드, build/release.ps1 원클릭 릴리스(-Publish/-DeploySite), build-remote.ps1 PowerShell 원격 빌드, upload-release-asset.ps1 로컬 실행 지원(.env 자동 로드·-Publish 승격·-Repo), fetch-releases.mjs 인증·폴백)을 수용하고, 덮여 사라진 감사 폴리시를 새 베이스에 재적용: 타이틀 em대시 제거+OG 메타(index/guide), 아이브로우 6→1(장식 점 제거), 히어로 2줄 헤드라인·20단어 서브·CTA 라벨 단일화·신뢰 스트립 제거, 파이프라인 3분리 카드→단일 머신드 레일 재구성, 과장 카피 완화(100%·1초·초고속·완벽), 시뮬레이터 예시 캡션, skip-link·focus-visible·hero__grid min-width:0(모바일 오버플로) 재적용 — 데스크톱/모바일 검증(scrollWidth 375==375, 아이브로우 1, 레일·캡션·탭 3종 확인), deploy-site.ps1 로 재배포 완료
This commit is contained in:
parent
9c9d9cb024
commit
f13914534a
11 changed files with 976 additions and 246 deletions
|
|
@ -1,35 +1,80 @@
|
|||
// 배포 전에 공개 릴리스 저장소의 릴리스 목록을 releases.json 으로 굽는다.
|
||||
// (브라우저에서 Forgejo API 를 직접 호출하면 CORS 에 막히므로 빌드 시점에 정적 생성)
|
||||
// 사용: node site/fetch-releases.mjs
|
||||
import { writeFileSync } from "node:fs";
|
||||
import { writeFileSync, readFileSync, existsSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const API = "https://git.chanpaca.net/api/v1/repos/Video-Downloader/releases/releases?limit=50";
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
const envPath = resolve(root, ".env");
|
||||
|
||||
const res = await fetch(API, { headers: { Accept: "application/json" } });
|
||||
if (!res.ok) throw new Error(`릴리스 API 실패: HTTP ${res.status}`);
|
||||
const raw = await res.json();
|
||||
// .env 로드 (환경변수가 없을 경우 보완)
|
||||
if (existsSync(envPath)) {
|
||||
const content = readFileSync(envPath, "utf8");
|
||||
for (const line of content.split("\n")) {
|
||||
const match = line.match(/^\s*([A-Za-z0-9_]+)\s*=\s*(.*)$/);
|
||||
if (match && !process.env[match[1]]) {
|
||||
process.env[match[1]] = match[2].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const releases = raw
|
||||
.filter((r) => !r.draft)
|
||||
.sort((a, b) => new Date(b.published_at) - new Date(a.published_at))
|
||||
.map((r) => ({
|
||||
tag: r.tag_name,
|
||||
name: r.name || r.tag_name,
|
||||
published_at: r.published_at,
|
||||
prerelease: r.prerelease,
|
||||
notes: r.body || "",
|
||||
assets: (r.assets || []).map((a) => ({
|
||||
name: a.name,
|
||||
size: a.size,
|
||||
url: a.browser_download_url,
|
||||
})),
|
||||
}));
|
||||
const serverUrl = (process.env.FORGEJO_URL || "https://git.chanpaca.net").replace(/\/$/, "");
|
||||
const repo = process.env.RELEASE_REPO || "Video-Downloader/releases";
|
||||
const API = `${serverUrl}/api/v1/repos/${repo}/releases?limit=50`;
|
||||
|
||||
const out = {
|
||||
generated_at: new Date().toISOString(),
|
||||
repo_url: "https://git.chanpaca.net/Video-Downloader/releases",
|
||||
releases,
|
||||
};
|
||||
const headers = { Accept: "application/json" };
|
||||
if (process.env.FORGEJO_TOKEN) {
|
||||
headers.Authorization = `token ${process.env.FORGEJO_TOKEN}`;
|
||||
} else if (process.env.FORGEJO_USER && process.env.FORGEJO_PASSWORD) {
|
||||
const b64 = Buffer.from(`${process.env.FORGEJO_USER}:${process.env.FORGEJO_PASSWORD}`).toString("base64");
|
||||
headers.Authorization = `Basic ${b64}`;
|
||||
}
|
||||
|
||||
writeFileSync(new URL("./releases.json", import.meta.url), JSON.stringify(out, null, 2));
|
||||
console.log(`releases.json 생성: 릴리스 ${releases.length}건`);
|
||||
const includeDraft = process.env.INCLUDE_DRAFT === "true";
|
||||
|
||||
try {
|
||||
const res = await fetch(API, { headers });
|
||||
if (!res.ok) throw new Error(`릴리스 API 실패: HTTP ${res.status}`);
|
||||
const raw = await res.json();
|
||||
|
||||
const releases = (Array.isArray(raw) ? raw : [])
|
||||
.filter((r) => includeDraft || !r.draft)
|
||||
.sort((a, b) => new Date(b.published_at || b.created_at) - new Date(a.published_at || a.created_at))
|
||||
.map((r) => ({
|
||||
tag: r.tag_name,
|
||||
name: r.name || r.tag_name,
|
||||
published_at: r.published_at || r.created_at,
|
||||
prerelease: r.prerelease,
|
||||
draft: r.draft,
|
||||
notes: r.body || "",
|
||||
assets: (r.assets || []).map((a) => ({
|
||||
name: a.name,
|
||||
size: a.size,
|
||||
url: a.browser_download_url,
|
||||
})),
|
||||
}));
|
||||
|
||||
const publicServerUrl = process.env.FORGEJO_PUBLIC_URL || "https://git.chanpaca.net";
|
||||
const out = {
|
||||
generated_at: new Date().toISOString(),
|
||||
repo_url: `${publicServerUrl.replace(/\/$/, "")}/${repo}`,
|
||||
releases,
|
||||
};
|
||||
|
||||
writeFileSync(new URL("./releases.json", import.meta.url), JSON.stringify(out, null, 2));
|
||||
console.log(`releases.json 생성 완료: 릴리스 ${releases.length}건 (저장소: ${repo})`);
|
||||
} catch (err) {
|
||||
console.error(`릴리스 정보 로드 실패: ${err.message}`);
|
||||
// 기존 releases.json 이 없으면 빈 파일 생성
|
||||
const outPath = resolve(__dirname, "releases.json");
|
||||
if (!existsSync(outPath)) {
|
||||
const fallback = {
|
||||
generated_at: new Date().toISOString(),
|
||||
repo_url: `${serverUrl}/${repo}`,
|
||||
releases: [],
|
||||
};
|
||||
writeFileSync(outPath, JSON.stringify(fallback, null, 2));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue