release(v2.3.2): 修复渲染模式复制图标比例 #53
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version (e.g. v1.0.0)' | |
| required: true | |
| type: string | |
| use_ci_build: | |
| description: 'Use CI build instead of local build upload (NOT recommended: CI builds have invisible text bug)' | |
| required: false | |
| type: boolean | |
| default: false | |
| env: | |
| SCHEME: MarkdownReader | |
| PRODUCT_NAME: MarkdownReader | |
| BUNDLE_ID: com.markdownreader.app | |
| permissions: | |
| contents: write | |
| jobs: | |
| # 默认模式:CI 仅创建 draft release 占位,等待本地 release-local.sh 上传产物 | |
| # 推送 tag 后执行: ./release-local.sh 构建并上传,然后 gh release edit --draft=false 发布 | |
| create-release: | |
| name: Create Release (await local upload) | |
| if: ${{ !inputs.use_ci_build }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Determine version | |
| id: version | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| TAG="${{ inputs.version }}" | |
| else | |
| TAG="${{ github.ref_name }}" | |
| fi | |
| VERSION="${TAG#v}" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Validate CHANGELOG | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| TAG="${{ steps.version.outputs.tag }}" | |
| if [ ! -f CHANGELOG.md ]; then | |
| echo "❌ CHANGELOG.md not found!" | |
| exit 1 | |
| fi | |
| if ! grep -q "\\[$VERSION\\]" CHANGELOG.md && ! grep -q "\\[$TAG\\]" CHANGELOG.md; then | |
| echo "❌ CHANGELOG.md does not contain version $VERSION or $TAG" | |
| exit 1 | |
| fi | |
| echo "✅ CHANGELOG.md validated for version $VERSION" | |
| - name: Create draft release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TAG="${{ steps.version.outputs.tag }}" | |
| VERSION="${{ steps.version.outputs.version }}" | |
| cat > /tmp/release-body.md << 'BODY' | |
| ## 安装说明 | |
| 1. 下载 `.dmg` 文件,双击打开 | |
| 2. 将 **Markdown Reader** 拖入 **Applications** 文件夹 | |
| 3. 首次打开时,macOS 可能提示「无法验证开发者」: | |
| - 打开 **系统设置 > 隐私与安全性** | |
| - 找到被阻止的 app,点击 **仍要打开** | |
| - 或在终端运行:`xattr -cr /Applications/MarkdownReader.app` | |
| 4. 也可以直接右键点击 app → 选择 **打开** | |
| --- | |
| BODY | |
| if [ -f "docs/releases/release-notes-${TAG}.md" ]; then | |
| cat "docs/releases/release-notes-${TAG}.md" >> /tmp/release-body.md | |
| elif [ -f "CHANGELOG.md" ]; then | |
| awk -v ver="$VERSION" ' | |
| /^## \[/ && section { exit } | |
| /^## \[/ && $0 ~ "\\[" ver "\\]" { section = 1 } | |
| section { print } | |
| ' CHANGELOG.md >> /tmp/release-body.md | |
| fi | |
| gh release create "$TAG" \ | |
| --title "$TAG" \ | |
| --draft \ | |
| --notes-file /tmp/release-body.md | |
| echo "✅ Draft release $TAG created" | |
| echo " 上传本地构建: ./release-local.sh $VERSION" | |
| echo " 发布: gh release edit $TAG --draft=false" | |
| # CI 构建作为后备(已知问题:CI 构建的编辑模式文字可能不可见) | |
| ci-build: | |
| name: Build & Release (CI fallback) | |
| if: ${{ inputs.use_ci_build }} | |
| runs-on: macos-15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Determine version | |
| id: version | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| TAG="${{ inputs.version }}" | |
| else | |
| TAG="${{ github.ref_name }}" | |
| fi | |
| VERSION="${TAG#v}" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Validate CHANGELOG | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| TAG="${{ steps.version.outputs.tag }}" | |
| if [ ! -f CHANGELOG.md ]; then | |
| echo "❌ CHANGELOG.md not found!" | |
| exit 1 | |
| fi | |
| if ! grep -q "\\[$VERSION\\]" CHANGELOG.md && ! grep -q "\\[$TAG\\]" CHANGELOG.md; then | |
| echo "❌ CHANGELOG.md does not contain version $VERSION or $TAG" | |
| exit 1 | |
| fi | |
| echo "✅ CHANGELOG.md validated for version $VERSION" | |
| - name: Install create-dmg | |
| run: brew install create-dmg | |
| - name: Build | |
| run: swift build -c release --arch arm64 | |
| - name: Patch Bundle.module resource paths | |
| run: | | |
| PATCHED=0 | |
| while IFS= read -r accessor; do | |
| if grep -q 'Bundle\.main\.bundleURL\.appendingPathComponent' "$accessor"; then | |
| sed -i '' 's/Bundle\.main\.bundleURL\.appendingPathComponent/(Bundle.main.resourceURL ?? Bundle.main.bundleURL).appendingPathComponent/g' "$accessor" | |
| PATCHED=$((PATCHED + 1)) | |
| echo "📝 Patched Bundle.module path: $accessor" | |
| fi | |
| done < <(find .build -name "resource_bundle_accessor.swift" -type f) | |
| if [[ "$PATCHED" -gt 0 ]]; then | |
| echo "🔨 Rebuilding with patched Bundle.module paths..." | |
| swift build -c release --arch arm64 | |
| else | |
| echo "✅ No patches needed (accessors already use resourceURL)" | |
| fi | |
| - name: Assemble .app bundle | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| APP_DIR="${{ env.PRODUCT_NAME }}.app" | |
| RESOURCES_DIR="$APP_DIR/Contents/Resources" | |
| MACOS_DIR="$APP_DIR/Contents/MacOS" | |
| mkdir -p "$MACOS_DIR" | |
| mkdir -p "$RESOURCES_DIR" | |
| BUILD_DIR=".build/arm64-apple-macosx/release" | |
| cp "$BUILD_DIR/${{ env.PRODUCT_NAME }}" "$MACOS_DIR/" | |
| sed "s/__VERSION__/$VERSION/g" scripts/Info.plist > "$APP_DIR/Contents/Info.plist" | |
| RESOURCE_BUNDLE="$BUILD_DIR/${{ env.PRODUCT_NAME }}_MarkdownReader.bundle" | |
| if [ -d "$RESOURCE_BUNDLE" ]; then | |
| cp -R "$RESOURCE_BUNDLE/" "$RESOURCES_DIR/" | |
| echo "✅ Copied SPM resource bundle" | |
| fi | |
| for bundle in "$BUILD_DIR"/*.bundle; do | |
| bundle_name=$(basename "$bundle") | |
| if [[ "$bundle_name" != "${{ env.PRODUCT_NAME }}_MarkdownReader.bundle" ]]; then | |
| cp -R "$bundle" "$RESOURCES_DIR/" | |
| echo "📦 Copied dependency bundle: $bundle_name" | |
| fi | |
| done | |
| echo "📦 Compiling Assets.xcassets with actool..." | |
| actool \ | |
| --compile "$RESOURCES_DIR" \ | |
| --platform macosx \ | |
| --minimum-deployment-target 26 \ | |
| --app-icon AppIcon \ | |
| --output-format human-readable-text \ | |
| --output-partial-info-plist /tmp/partial.plist \ | |
| "Sources/${{ env.PRODUCT_NAME }}/Assets.xcassets" | |
| echo -n "APPL????" > "$APP_DIR/Contents/PkgInfo" | |
| echo "✅ .app bundle assembled" | |
| - name: Code sign .app | |
| run: | | |
| # 不使用 --deep(Apple 已弃用),分别签名 bundle 和主 app | |
| find "${{ env.PRODUCT_NAME }}.app/Contents/Resources" -name "*.bundle" -exec codesign --force --sign - {} \; 2>/dev/null || true | |
| codesign --force --sign - "${{ env.PRODUCT_NAME }}.app" | |
| echo "✅ App signed (ad-hoc)" | |
| - name: Create DMG | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| DMG_NAME="${{ env.PRODUCT_NAME }}-$VERSION.dmg" | |
| rm -f "$DMG_NAME" | |
| create-dmg \ | |
| --volname "${{ env.PRODUCT_NAME }} $VERSION" \ | |
| --volicon "${{ env.PRODUCT_NAME }}.app/Contents/Resources/AppIcon.icns" \ | |
| --window-pos 200 120 \ | |
| --window-size 600 400 \ | |
| --icon-size 100 \ | |
| --icon "${{ env.PRODUCT_NAME }}.app" 175 190 \ | |
| --app-drop-link 425 190 \ | |
| "$DMG_NAME" \ | |
| "${{ env.PRODUCT_NAME }}.app" | |
| VOLICON="${{ env.PRODUCT_NAME }}.app/Contents/Resources/AppIcon.icns" | |
| if [ -f "$VOLICON" ]; then | |
| swiftc scripts/seticon.swift -o /tmp/seticon | |
| /tmp/seticon "$VOLICON" "$DMG_NAME" | |
| fi | |
| echo "dmg_name=$DMG_NAME" >> "$GITHUB_ENV" | |
| - name: Create ZIP | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| ZIP_NAME="${{ env.PRODUCT_NAME }}-$VERSION.zip" | |
| zip -r "$ZIP_NAME" "${{ env.PRODUCT_NAME }}.app" | |
| echo "zip_name=$ZIP_NAME" >> "$GITHUB_ENV" | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TAG="${{ steps.version.outputs.tag }}" | |
| VERSION="${{ steps.version.outputs.version }}" | |
| DMG_NAME="${{ env.PRODUCT_NAME }}-$VERSION.dmg" | |
| ZIP_NAME="${{ env.PRODUCT_NAME }}-$VERSION.zip" | |
| cat > /tmp/release-body.md << 'BODY' | |
| ## 安装说明 | |
| 1. 下载 `.dmg` 文件,双击打开 | |
| 2. 将 **Markdown Reader** 拖入 **Applications** 文件夹 | |
| 3. 首次打开时,macOS 可能提示「无法验证开发者」: | |
| - 打开 **系统设置 > 隐私与安全性** | |
| - 找到被阻止的 app,点击 **仍要打开** | |
| - 或在终端运行:`xattr -cr /Applications/MarkdownReader.app` | |
| 4. 也可以直接右键点击 app → 选择 **打开** | |
| --- | |
| BODY | |
| if [ -f "docs/releases/release-notes-${TAG}.md" ]; then | |
| cat "docs/releases/release-notes-${TAG}.md" >> /tmp/release-body.md | |
| elif [ -f "CHANGELOG.md" ]; then | |
| awk -v ver="$VERSION" ' | |
| /^## \[/ && section { exit } | |
| /^## \[/ && $0 ~ "\\[" ver "\\]" { section = 1 } | |
| section { print } | |
| ' CHANGELOG.md >> /tmp/release-body.md | |
| fi | |
| gh release create "$TAG" \ | |
| --title "$TAG" \ | |
| --notes-file /tmp/release-body.md \ | |
| "$DMG_NAME" \ | |
| "$ZIP_NAME" | |
| echo "✅ GitHub Release $TAG created" |