Skip to content

1

1 #792

Workflow file for this run

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: |
# 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
COMMIT_HISTORY=$(git log $COMMIT_RANGE --pretty=format:'- %s (%h)%n%b')
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
# Make the history safe for JSON
JSON_SAFE_HISTORY=$(echo "$COMMIT_HISTORY" | sed 's/\\/\\\\/g' | sed 's/"/\"/g' | awk '{printf "%s\n", $0}' ORS='')
# Prepare the prompt for the AI
PROMPT="你是一个版本发布小助手。请根据以下自上次发布以来的 git commit 记录,为我生成一份精美的中文更新日志。请在日志中清晰地标注每次更新分别来自哪一次 commit (使用 commit hash),如果 commit 信息中提到了 PR (#<number>) 或 Issue (#<number>),也请一并展示。不需要使用代码框包裹。请确保排版优雅,重点突出,精准整理,优雅氛围不同板块罗列,包含新内容,已有功能改动,bug修复。以下是 commit 记录:${JSON_SAFE_HISTORY}请直接返回 Markdown 格式的更新日志内容,不要包含其他额外的话,不要使用emoji。"
# Create the JSON payload using jq
JSON_PAYLOAD=$(jq -n \
--arg model "gpt-5" \
--argjson temp 0.5 \
--arg role "user" \
--arg content "$PROMPT" \
'{model: $model, temperature: $temp, messages: [{role: $role, content: $content}]}')
# Call the AI API and save the response
echo "Sending request to AI for changelog summary..."
AI_RESPONSE=$(curl -s -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. Fallback to raw commit history on failure.
if echo "$AI_RESPONSE" | jq -e '.choices[0].message.content' > /dev/null; then
echo "Successfully received changelog from AI."
echo "$AI_RESPONSE" | jq -r '.choices[0].message.content' > release_notes.md
else
echo "Warning: Failed to get a valid response from the AI API. Using raw commit history as fallback."
echo "API Response: $AI_RESPONSE"
echo -e "# 更新日志\n\n无法从 AI 服务获取本次更新的摘要。以下是自上次发布以来的提交记录:\n\n```\n${COMMIT_HISTORY}\n```" > release_notes.md
fi
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