Skip to content

Commit 36b0192

Browse files
committed
ci: add github actions workflow for github pages deployment
1 parent 7e7cb33 commit 36b0192

14 files changed

Lines changed: 221 additions & 96 deletions

File tree

‎.github/workflows/deploy.yml‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Deploy NextTorrent to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
10+
permissions:
11+
contents: read
12+
pages: write
13+
id-token: write
14+
15+
# Allow one concurrent deployment
16+
concurrency:
17+
group: 'pages'
18+
cancel-in-progress: false
19+
20+
jobs:
21+
build:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 20
31+
cache: 'npm'
32+
33+
- name: Setup GitHub Pages
34+
id: pages
35+
uses: actions/configure-pages@v5
36+
37+
- name: Install dependencies
38+
run: npm ci
39+
40+
- name: Build static export
41+
run: npm run build
42+
env:
43+
GITHUB_PAGES: 'true'
44+
NEXT_PUBLIC_BASE_PATH: ${{ steps.pages.outputs.base_path }}
45+
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
46+
47+
- name: Upload Pages artifact
48+
uses: actions/upload-pages-artifact@v3
49+
with:
50+
path: ./out
51+
52+
deploy:
53+
environment:
54+
name: github-pages
55+
url: ${{ steps.deployment.outputs.page_url }}
56+
runs-on: ubuntu-latest
57+
needs: build
58+
steps:
59+
- name: Deploy to GitHub Pages
60+
id: deployment
61+
uses: actions/deploy-pages@v4

‎README.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ User → nginx:80 → Next.js (app):3000 → External torrent APIs/Pages
2424

2525
## Quick Start
2626

27+
### Live Demo
28+
29+
Demo URL: **[https://OriginZero.github.io/NextTorrent/](https://OriginZero.github.io/NextTorrent/)**
30+
31+
> Statically exported and deployed to GitHub Pages via GitHub Actions.
32+
2733
### Development
2834

2935
```bash
@@ -32,6 +38,15 @@ npm run dev
3238
# http://localhost:3000
3339
```
3440

41+
### GitHub Actions Deployment (GitHub Pages)
42+
43+
Configured with `.github/workflows/deploy.yml`. Pushing to the `main` branch will automatically build and publish to GitHub Pages.
44+
45+
**Enable GitHub Pages for the first time:**
46+
1. Navigate to repository `Settings` → `Pages`
47+
2. Under `Build and deployment` > `Source`, select **GitHub Actions**
48+
3. (Optional) To connect a custom external backend by default, add a Repository Secret under `Settings` → `Secrets and variables` → `Actions`: `NEXT_PUBLIC_API_URL` (e.g. `https://your-api.com`)
49+
3550
### Docker
3651

3752
```bash

‎README.zh.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
## 快速开始
2626

27+
### 在线体验地址
28+
29+
体验地址:**[https://OriginZero.github.io/NextTorrent/](https://OriginZero.github.io/NextTorrent/)**
30+
31+
> 页面通过 GitHub Actions 自动化静态导出并部署至 GitHub Pages。
32+
2733
### 开发模式
2834

2935
```bash
@@ -32,6 +38,15 @@ npm run dev
3238
# http://localhost:3000
3339
```
3440

41+
### GitHub Actions 自动化部署 (GitHub Pages)
42+
43+
本项目已配置 `.github/workflows/deploy.yml`。推送代码至 `main` 分支时将自动构建并发布到 GitHub Pages。
44+
45+
**首次使用请在 GitHub 仓库中开启 Pages:**
46+
1. 进入 GitHub 仓库设置:`Settings` → `Pages`
47+
2. 将 `Build and deployment` 的 `Source` 设置为 **GitHub Actions**
48+
3. (可选)如需默认连接自定义外部后端,可在 `Settings` → `Secrets and variables` → `Actions` 中添加 Repository secret:`NEXT_PUBLIC_API_URL`(例如 `https://your-api.com`)
49+
3550
### Docker 部署
3651

3752
```bash

‎eslint.config.mjs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import nextTs from "eslint-config-next/typescript";
55
const eslintConfig = defineConfig([
66
...nextVitals,
77
...nextTs,
8+
{
9+
rules: {
10+
"@typescript-eslint/no-explicit-any": "off",
11+
"@typescript-eslint/no-unused-vars": "warn",
12+
},
13+
},
814
// Override default ignores of eslint-config-next.
915
globalIgnores([
1016
// Default ignores of eslint-config-next:

‎next.config.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import type { NextConfig } from "next";
22

3+
const isExport = process.env.OUTPUT_EXPORT === 'true' || process.env.GITHUB_PAGES === 'true';
4+
35
const nextConfig: NextConfig = {
4-
output: 'standalone',
6+
output: isExport ? 'export' : 'standalone',
7+
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
8+
images: {
9+
unoptimized: true,
10+
},
511
};
612

713
export default nextConfig;

‎src/app/ClientLayout.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client'
22

33
import { ReactNode } from 'react'
4+
import Link from 'next/link'
45
import { I18nProvider, useI18n } from '@/lib/i18n/context'
56

67
function LangSwitcher() {
@@ -17,7 +18,7 @@ export default function ClientLayout({ children }: { children: ReactNode }) {
1718
return (
1819
<I18nProvider>
1920
<header className="flex items-center justify-between px-4 py-2 border-b border-zinc-200 dark:border-zinc-800">
20-
<a href="/" className="font-bold text-lg">TorrentNext</a>
21+
<Link href="/" className="font-bold text-lg">TorrentNext</Link>
2122
<LangSwitcher />
2223
</header>
2324
<main className="flex flex-col flex-1">{children}</main>

‎src/app/api/health/route.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { NextResponse } from 'next/server'
22

3+
export const dynamic = 'force-static'
4+
35
export async function GET() {
46
return NextResponse.json({ status: 'ok', timestamp: new Date().toISOString() })
57
}

‎src/app/api/providers/route.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { SearchProvidersManager } from '@/lib/manager'
55
const manager = new SearchProvidersManager()
66
const gateway = new SearchProvidersGateway(manager)
77

8+
export const dynamic = 'force-static'
9+
810
export async function GET() {
911
const providers = manager.getEnabledProviders().map(p => ({
1012
id: p.id,

‎src/app/api/search/route.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { Category } from '@/lib/types'
66
const manager = new SearchProvidersManager()
77
const gateway = new SearchProvidersGateway(manager)
88

9+
export const dynamic = 'force-static'
10+
911
export async function GET(req: NextRequest) {
1012
const q = req.nextUrl.searchParams.get('q')
1113
if (!q) return NextResponse.json({ error: 'Missing query parameter: q' }, { status: 400 })

‎src/app/api/torrent/details/route.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { SearchProvidersManager } from '@/lib/manager'
55
const manager = new SearchProvidersManager()
66
const gateway = new SearchProvidersGateway(manager)
77

8+
export const dynamic = 'force-static'
9+
810
export async function GET(req: NextRequest) {
911
const url = req.nextUrl.searchParams.get('url')
1012
const provider = req.nextUrl.searchParams.get('provider')

0 commit comments

Comments
 (0)