docs: refactor and beautify README structure and layout #800
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build & Release (Modular) | |
| # Trigger on push to the main branch | |
| on: | |
| push: | |
| branches: | |
| - 'main' | |
| # If previous workflow is still running, we push again, we will cancel the previous workflow | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref_name }} | |
| cancel-in-progress: true | |
| jobs: | |
| Gatekeeper: | |
| name: Check Commit Message | |
| runs-on: ubuntu-latest | |
| outputs: | |
| triggered: ${{ steps.check.outputs.triggered }} | |
| release_title: ${{ steps.check.outputs.release_title }} | |
| steps: | |
| - name: Check commit message for release trigger | |
| id: check | |
| run: | | |
| COMMIT_MSG="${{ github.event.head_commit.message }}" | |
| if [[ "$COMMIT_MSG" =~ ([0-9]{4}\.[0-9]{4}) ]]; then | |
| echo "✅ Release trigger found in commit message." | |
| echo "triggered=true" >> $GITHUB_OUTPUT | |
| echo "release_title=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT | |
| else | |
| echo "🛑 No release trigger found. Skipping release workflow." | |
| echo "triggered=false" >> $GITHUB_OUTPUT | |
| fi | |
| # 并行构建所有平台,支持fail-fast: false策略 | |
| Build-Android: | |
| name: Build Android | |
| needs: Gatekeeper | |
| if: needs.Gatekeeper.outputs.triggered == 'true' | |
| uses: ./.github/workflows/build-android.yml | |
| secrets: | |
| SIGNING_KEY: ${{ secrets.SIGNING_KEY }} | |
| KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} | |
| ALIAS: ${{ secrets.ALIAS }} | |
| KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} | |
| Build-macOS: | |
| name: Build macOS | |
| needs: Gatekeeper | |
| if: needs.Gatekeeper.outputs.triggered == 'true' | |
| uses: ./.github/workflows/build-macos.yml | |
| secrets: | |
| MACOS_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }} | |
| MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} | |
| Build-Windows: | |
| name: Build Windows | |
| needs: Gatekeeper | |
| if: needs.Gatekeeper.outputs.triggered == 'true' | |
| uses: ./.github/workflows/build-windows.yml | |
| Build-Linux: | |
| name: Build Linux | |
| needs: Gatekeeper | |
| if: needs.Gatekeeper.outputs.triggered == 'true' | |
| uses: ./.github/workflows/build-linux.yml | |
| Publish: | |
| name: Publish Release | |
| needs: [Gatekeeper, Build-Android, Build-macOS, Build-Windows, Build-Linux] | |
| if: needs.Gatekeeper.outputs.triggered == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Required to get all commit history for changelog | |
| - name: Download all Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/artifacts | |
| - name: List all Artifacts | |
| run: ls -R /tmp/artifacts | |
| - name: Generate Changelog with AI | |
| id: ai_changelog | |
| run: | | |
| set -euo pipefail | |
| # Install jq to parse JSON response | |
| sudo apt-get install -y jq | |
| # Get the latest and previous tag. If no previous tag, use the first commit. | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$LATEST_TAG" ]; then | |
| echo "No previous tag found. Using full history." | |
| COMMIT_RANGE="$(git rev-list --max-parents=0 HEAD)..HEAD" | |
| else | |
| echo "Last release was at tag: $LATEST_TAG" | |
| COMMIT_RANGE="$LATEST_TAG..HEAD" | |
| fi | |
| # Get commit history since the last tag | |
| MAX_COMMITS=200 | |
| COMMIT_HISTORY=$(git log $COMMIT_RANGE --pretty=format:'- %s (%h)' -n $MAX_COMMITS) | |
| if [ -z "$COMMIT_HISTORY" ]; then | |
| echo "No new commits since last tag. Using latest commit message as changelog." | |
| COMMIT_HISTORY=$(git log -1 --pretty=format:'- %s (%h)') | |
| fi | |
| # Create the JSON payload using jq | |
| JSON_PAYLOAD=$(jq -n \ | |
| --arg model "gpt-5" \ | |
| --argjson temp 0.5 \ | |
| --arg history "$COMMIT_HISTORY" \ | |
| '{model: $model, temperature: $temp, messages: [{role: "user", content: ("你是一个版本发布小助手。请根据以下自上次发布以来的 git commit 记录,为我生成一份精美的中文更新日志。请在日志中清晰地标注每次更新分别来自哪一次 commit (使用 commit hash),如果 commit 信息中提到了 PR (#<number>) 或 Issue (#<number>),也请一并展示。不需要使用代码框包裹。请确保排版优雅,重点突出,精准整理,优雅氛围不同板块罗列,包含新内容,已有功能改动,bug修复。以下是 commit 记录:\n" + $history + "\n请直接返回 Markdown 格式的更新日志内容,不要包含其他额外的话,不要使用emoji。")]}') | |
| # Call the AI API and save the response | |
| echo "Sending request to AI for changelog summary..." | |
| AI_RESPONSE=$(curl -fsS -X POST https://ffmpeg.dfsteve.top/git.php \ | |
| -H "Content-Type: application/json; charset=utf-8" \ | |
| -d "$JSON_PAYLOAD") | |
| # Extract the content and write to a file. | |
| echo "$AI_RESPONSE" | jq -er '.choices[0].message.content' > release_notes.md | |
| echo "--- Generated Release Notes ---" | |
| cat release_notes.md | |
| echo "-------------------------------" | |
| - name: Upload to release | |
| uses: ncipollo/release-action@v1 | |
| with: | |
| tag: v${{ needs.Build-Android.outputs.version }} | |
| name: Release v${{ needs.Build-Android.outputs.version }} | |
| bodyFile: "release_notes.md" | |
| allowUpdates: true | |
| artifacts: /tmp/artifacts/release-Android/*.apk,/tmp/artifacts/release-macOS/*.dmg,/tmp/artifacts/release-Windows-x64/*.zip,/tmp/artifacts/release-Windows-x64/*.exe,/tmp/artifacts/release-Linux-amd64/*.deb,/tmp/artifacts/release-Linux-amd64/*.AppImage,/tmp/artifacts/release-Linux-amd64/*.tar.gz,/tmp/artifacts/release-Linux-amd64/*.rpm,/tmp/artifacts/release-Linux-arm64/*.deb,/tmp/artifacts/release-Linux-arm64/*.tar.gz,/tmp/artifacts/release-Linux-arm64/*.rpm | |
| artifactErrorsFailBuild: true | |
| replacesArtifacts: true | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| UpdateVersion: | |
| needs: [Publish] | |
| if: success() # This job runs only if Publish job succeeds | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Update version | |
| run: | | |
| git config --global user.name 'github-actions[bot]' | |
| git config --global user.email 'github-actions[bot]@users.noreply.github.com' | |
| # Get latest code | |
| git fetch origin refs/heads/main:refs/remotes/origin/main | |
| git checkout -B main refs/remotes/origin/main | |
| # Read and update version | |
| CURRENT_VERSION=$(grep '^version:' pubspec.yaml | cut -d ' ' -f 2) | |
| echo "Current version: $CURRENT_VERSION" | |
| MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1) | |
| MINOR=$(echo $CURRENT_VERSION | cut -d. -f2) | |
| PATCH=$(echo $CURRENT_VERSION | cut -d. -f3) | |
| NEW_PATCH=$((PATCH + 1)) | |
| NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH" | |
| echo "New version: $NEW_VERSION" | |
| # Update pubspec.yaml | |
| sed -i "s/^version: .*$/version: $NEW_VERSION/" pubspec.yaml | |
| # Commit and push changes | |
| git add pubspec.yaml | |
| git commit -m "chore: bump version to $NEW_VERSION [skip ci]" | |
| git push origin refs/heads/main | |
| UpdateHomebrewTap: | |
| name: Update Homebrew Tap | |
| needs: [Publish, Build-macOS] | |
| if: success() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Homebrew Tap repository | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Shinokawa/homebrew-nipaplay-reload | |
| path: homebrew-tap | |
| token: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| - name: Get Version | |
| id: get_version | |
| run: echo "version=${{ needs.Build-macOS.outputs.version }}" >> $GITHUB_OUTPUT | |
| - name: Calculate SHA256 of the DMG | |
| id: shasum | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| DMG_URL="https://github.com/MCDFsteve/NipaPlay-Reload/releases/download/v${VERSION}/NipaPlay_${VERSION}_macOS_Universal.dmg" | |
| echo "Downloading DMG from ${DMG_URL}..." | |
| curl -sL -o NipaPlay.dmg "${DMG_URL}" | |
| echo "Calculating SHA256..." | |
| SHA256=$(shasum -a 256 NipaPlay.dmg | awk '{print $1}') | |
| echo "SHA256 is ${SHA256}" | |
| echo "sha256=${SHA256}" >> $GITHUB_OUTPUT | |
| - name: Update Cask file | |
| run: | | |
| CASK_FILE="homebrew-tap/Casks/nipaplay-reload.rb" | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| SHA256="${{ steps.shasum.outputs.sha256 }}" | |
| echo "Updating ${CASK_FILE} to version ${VERSION}" | |
| sed -i 's/^ version ".*"/ version "'"${VERSION}"'"/' "${CASK_FILE}" | |
| sed -i 's/^ sha256 ".*"/ sha256 "'"${SHA256}"'"/' "${CASK_FILE}" | |
| # Also update the zap trash paths to use correct Bundle ID | |
| sed -i 's|"~/Library/Preferences/io\.github\.mcdfsteve\.nipaplay-reload\.plist"|"~/Library/Preferences/com.aimessoft.nipaplay.plist"|g' "${CASK_FILE}" | |
| sed -i 's|"~/Library/Saved Application State/io\.github\.mcdfsteve\.nipaplay-reload\.savedState"|"~/Library/Saved Application State/com.aimessoft.nipaplay.savedState"|g' "${CASK_FILE}" | |
| sed -i 's|"~/Library/Application Support/NipaPlay-Reload"|"~/Library/Application Support/NipaPlay"|g' "${CASK_FILE}" | |
| echo "--- Cask file content after update ---" | |
| cat "${CASK_FILE}" | |
| echo "--------------------------------------" | |
| - name: Commit and push Cask update | |
| run: | | |
| cd homebrew-tap | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| if [[ -z $(git status -s) ]]; then | |
| echo "No changes to the Cask file. Skipping commit." | |
| else | |
| echo "Changes detected. Committing and pushing..." | |
| git add Casks/nipaplay-reload.rb | |
| git commit -m "Update nipaplay-reload cask to v${{ steps.get_version.outputs.version }}" | |
| git push | |
| echo "Push successful." | |
| fi |