diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index bd055cb..438497f 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,11 +1,6 @@ name: Build & Push Docker image on: - push: - branches: - - main - paths-ignore: - - '**.md' pull_request_target: branches: - main @@ -15,6 +10,10 @@ on: types: - labeled - synchronize + workflow_run: + workflows: ['Release'] + types: + - completed workflow_dispatch: @@ -61,22 +60,20 @@ jobs: id: lowercase run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" - - name: Get version from VERSION.txt - id: version - run: | - VERSION=$(cat VERSION.txt | tr -d '[:space:]') - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "Current version: $VERSION" - - name: Extract metadata id: meta uses: docker/metadata-action@v5 + with: images: ghcr.io/${{ steps.lowercase.outputs.owner }}/moontv tags: | type=ref,event=pr type=raw,value=latest,enable={{is_default_branch}} - type=raw,value={{steps.version.outputs.version}} + type=match,pattern=v(.*),group=1,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Get latest tag + run: | + echo "latest_tag=$(curl -s https://api.github.com/repos/${{ github.repository }}/tags | jq -r '.[0].name // "latest"' | sed 's/^v//')" >> $GITHUB_ENV - name: Build and push by digest id: build @@ -86,7 +83,8 @@ jobs: file: ./Dockerfile platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} - outputs: type=image,name=ghcr.io/${{ steps.lowercase.outputs.owner }}/moontv,push-by-digest=true,name-canonical=true,push=true + tags: ghcr.io/${{ steps.lowercase.outputs.owner }}/moontv:${{ env.latest_tag }} + outputs: type=image,name=ghcr.io/${{ steps.lowercase.outputs.owner }}/moontv,name-canonical=true,push=true - name: Export digest run: | @@ -128,13 +126,6 @@ jobs: id: lowercase run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" - - name: Get version from VERSION.txt - id: version - run: | - VERSION=$(cat VERSION.txt | tr -d '[:space:]') - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "Current version: $VERSION" - - name: Extract metadata id: meta uses: docker/metadata-action@v5 @@ -143,7 +134,7 @@ jobs: tags: | type=ref,event=pr,prefix=pr- type=raw,value=latest,enable={{is_default_branch}} - type=raw,value={{steps.version.outputs.version}} + type=match,pattern=v(.*),group=1,enable=${{ startsWith(github.ref, 'refs/tags/v') }} - name: Create manifest list and push working-directory: /tmp/digests @@ -187,7 +178,7 @@ jobs: 构建完成时间:${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}` }); - cleanup: + cleanup-refresh: runs-on: ubuntu-latest needs: - merge @@ -200,13 +191,6 @@ jobs: repository: ${{ github.repository }} retain_days: 0 keep_minimum_runs: 2 - - version-cache-refresh: - runs-on: ubuntu-latest - needs: - - cleanup - if: always() && github.event_name != 'pull_request_target' - steps: - name: Refresh VERSION.txt cache run: | echo "Refreshing VERSION.txt cache..." diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..d5edfa5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,96 @@ +name: Release + +on: + push: + tags: + - 'v*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + env: + TZ: Asia/Shanghai + steps: + - name: Checkout source code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Extract version from tag + id: version + run: | + VERSION=${GITHUB_REF#refs/tags/v} + TAG_NAME=${GITHUB_REF#refs/tags/} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "tag=$TAG_NAME" >> $GITHUB_OUTPUT + echo "Version: $VERSION" + echo "Tag: $TAG_NAME" + + - name: Get tag message + id: tag_message + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG_NAME=${{ steps.version.outputs.tag }} + RELEASE_BODY=$(gh release view "$TAG_NAME" --json body -q .body || echo "") + printf '%s\n' "$RELEASE_BODY" > /tmp/tag_message.txt + echo "Tag message saved to /tmp/tag_message.txt" + echo "Tag message content:" + cat /tmp/tag_message.txt + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Update version files and generate changelog + run: | + CURRENT_DATE=$(date +%Y-%m-%d) + VERSION="${{ steps.version.outputs.version }}" + TAG_MESSAGE=$(cat /tmp/tag_message.txt) + echo "Updating CHANGELOG file..." + { + echo "## [$VERSION] - $CURRENT_DATE" + echo "" + cat /tmp/tag_message.txt + echo "" + } > /tmp/new_entry.txt + + if [ -f "CHANGELOG" ]; then + cp CHANGELOG CHANGELOG.bak + cat /tmp/new_entry.txt CHANGELOG.bak > CHANGELOG + else + cp /tmp/new_entry.txt CHANGELOG + fi + echo "✅ Updated CHANGELOG with new entry for version $VERSION" + + echo "Updating VERSION.txt..." + echo "$VERSION" > VERSION.txt + echo "✅ Updated VERSION.txt to $VERSION" + + echo "Generating changelog TypeScript file..." + node scripts/convert-changelog.js + + echo "Updating version.ts..." + sed -i "s/const CURRENT_VERSION = '[^']*';/const CURRENT_VERSION = '$VERSION';/" src/lib/version.ts + echo "✅ Updated version.ts to $VERSION" + + - name: Commit generated files + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add CHANGELOG VERSION.txt src/lib/changelog.ts src/lib/version.ts + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "chore: Bump to ${{ steps.version.outputs.version }}" + git push origin HEAD:main + echo "Committed and pushed generated files" + fi diff --git a/.husky/pre-commit b/.husky/pre-commit index 7a0491e..c37466e 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,9 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -pnpm gen:changelog -git add VERSION.txt -git add src/lib/version.ts -git add src/lib/changelog.ts - npx lint-staged \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG index 5562616..9bf07ed 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,32 @@ -## [1.0.4] - 2025-08-12 +## [1.1.1] - 2025-08-12 + +### Changed +- 修正 zwei 提供的 cors proxy 地址 +- 移除废弃代码 + +### Fixed +- [运维] docker workflow release 日期使用东八区日期 + +## [1.1.0] - 2025-08-12 + +### Added +- 每日新番放送功能,展示每日新番放送的番剧 + +### Fixed +- 修复远程 CHANGELOG 无法提取变更内容的问题 + +## [1.0.5] - 2025-08-12 + +### Changed +- 实现基于 Git 标签的自动 Release 工作流 + +## [1.0.4] - 2025-08-11 ### Added - 优化版本管理工作流,实现单点修改 ### Changed -- 版本号现在从CHANGELOG自动提取,无需手动维护VERSION.txt +- 版本号现在从 CHANGELOG 自动提取,无需手动维护 VERSION.txt ## [1.0.3] - 2025-08-11 diff --git a/VERSION.txt b/VERSION.txt index a6a3a43..8cfbc90 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.0.4 \ No newline at end of file +1.1.1 \ No newline at end of file diff --git a/package.json b/package.json index a28754d..61be790 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "format:check": "prettier -c .", "gen:runtime": "node scripts/convert-config.js", "gen:manifest": "node scripts/generate-manifest.js", - "gen:changelog": "node scripts/convert-changelog.js", "postbuild": "echo 'Build completed - sitemap generation disabled'", "prepare": "husky install" }, diff --git a/scripts/convert-changelog.js b/scripts/convert-changelog.js index 66fd166..c88c8f8 100644 --- a/scripts/convert-changelog.js +++ b/scripts/convert-changelog.js @@ -10,6 +10,7 @@ function parseChangelog(content) { const versions = []; let currentVersion = null; let currentSection = null; + let inVersionContent = false; for (const line of lines) { const trimmedLine = line.trim(); @@ -29,27 +30,38 @@ function parseChangelog(content) { added: [], changed: [], fixed: [], + content: [], // 用于存储原始内容,当没有分类时使用 }; currentSection = null; + inVersionContent = true; continue; } - // 匹配章节标题 - if (trimmedLine === '### Added') { - currentSection = 'added'; - continue; - } else if (trimmedLine === '### Changed') { - currentSection = 'changed'; - continue; - } else if (trimmedLine === '### Fixed') { - currentSection = 'fixed'; - continue; - } + // 如果遇到下一个版本或到达文件末尾,停止处理当前版本 + if (inVersionContent && currentVersion) { + // 匹配章节标题 + if (trimmedLine === '### Added') { + currentSection = 'added'; + continue; + } else if (trimmedLine === '### Changed') { + currentSection = 'changed'; + continue; + } else if (trimmedLine === '### Fixed') { + currentSection = 'fixed'; + continue; + } - // 匹配条目: - 内容 - if (trimmedLine.startsWith('- ') && currentSection && currentVersion) { - const entry = trimmedLine.substring(2); - currentVersion[currentSection].push(entry); + // 匹配条目: - 内容 + if (trimmedLine.startsWith('- ') && currentSection) { + const entry = trimmedLine.substring(2); + currentVersion[currentSection].push(entry); + } else if ( + trimmedLine && + !trimmedLine.startsWith('#') && + !trimmedLine.startsWith('###') + ) { + currentVersion.content.push(trimmedLine); + } } } @@ -58,6 +70,19 @@ function parseChangelog(content) { versions.push(currentVersion); } + // 后处理:如果某个版本没有分类内容,但有 content,则将 content 放到 changed 中 + versions.forEach((version) => { + const hasCategories = + version.added.length > 0 || + version.changed.length > 0 || + version.fixed.length > 0; + if (!hasCategories && version.content.length > 0) { + version.changed = version.content; + } + // 清理 content 字段 + delete version.content; + }); + return { versions }; } @@ -170,10 +195,19 @@ function main() { fs.writeFileSync(outputPath, tsContent, 'utf-8'); - // 更新版本文件 - console.log('正在更新版本文件...'); - updateVersionFile(latestVersion); - updateVersionTs(latestVersion); + // 检查是否在 GitHub Actions 环境中运行 + const isGitHubActions = process.env.GITHUB_ACTIONS === 'true'; + + if (isGitHubActions) { + // 在 GitHub Actions 中,更新版本文件 + console.log('正在更新版本文件...'); + updateVersionFile(latestVersion); + updateVersionTs(latestVersion); + } else { + // 在本地运行时,只提示但不更新版本文件 + console.log('🔧 本地运行模式:跳过版本文件更新'); + console.log('💡 版本文件更新将在 git tag 触发的 release 工作流中完成'); + } console.log(`✅ 成功生成 ${outputPath}`); console.log(`📊 版本统计:`); @@ -183,7 +217,7 @@ function main() { ); }); - console.log('\n🎉 所有更新完成!'); + console.log('\n🎉 转换完成!'); } catch (error) { console.error('❌ 转换失败:', error); process.exit(1); diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 63c7e10..bdf7691 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -148,10 +148,7 @@ const UserConfig = ({ config, role, refreshConfig }: UserConfigProps) => { // 当前登录用户名 const currentUsername = getAuthInfoFromBrowserCookie()?.username || null; - // 检测存储类型是否为 d1 - const isD1Storage = - typeof window !== 'undefined' && - (window as any).RUNTIME_CONFIG?.STORAGE_TYPE === 'd1'; + // 检测存储类型是否为 upstash const isUpstashStorage = typeof window !== 'undefined' && (window as any).RUNTIME_CONFIG?.STORAGE_TYPE === 'upstash'; @@ -317,15 +314,10 @@ const UserConfig = ({ config, role, refreshConfig }: UserConfigProps) => {
- {category.from !== 'config' && !isD1Storage && !isUpstashStorage && ( + {category.from !== 'config' && !isUpstashStorage && (
- {showAddForm && !isD1Storage && !isUpstashStorage && ( + {showAddForm && !isUpstashStorage && (
{/* 保存排序按钮 */} - {orderChanged && !isD1Storage && !isUpstashStorage && ( + {orderChanged && !isUpstashStorage && (