feat: 添加阅读中书签分类功能 (#71) #58
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 | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| actions: read | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - beta | |
| workflow_dispatch: | |
| inputs: | |
| skip_approval: | |
| description: '跳过手动确认步骤' | |
| required: false | |
| default: false | |
| type: boolean | |
| jobs: | |
| test: | |
| uses: ./.github/workflows/test.yml | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| actions: read | |
| approval: | |
| name: Manual Approval Required | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: | | |
| github.event_name == 'push' && | |
| (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') && | |
| !contains(github.event.head_commit.message, '[skip ci]') && | |
| !contains(github.event.head_commit.message, 'chore: sync beta with main') && | |
| !github.event.inputs.skip_approval | |
| environment: production-approval | |
| steps: | |
| - name: Manual approval checkpoint | |
| run: | | |
| echo "等待手动确认部署..." | |
| echo "分支: ${{ github.ref }}" | |
| echo "提交: ${{ github.event.head_commit.message }}" | |
| echo "提交者: ${{ github.event.head_commit.author.name }}" | |
| release: | |
| name: Release | |
| runs-on: ubuntu-latest | |
| needs: [test, approval] | |
| if: | | |
| (github.event_name == 'push' && | |
| (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') && | |
| !contains(github.event.head_commit.message, '[skip ci]') && | |
| !contains(github.event.head_commit.message, 'chore: sync beta with main')) || | |
| (github.event_name == 'workflow_dispatch' && github.event.inputs.skip_approval == 'true') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Cache npm dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-npm- | |
| - name: Install semantic-release dependencies | |
| run: npm ci | |
| - name: Setup Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: "zulu" | |
| java-version: "17" | |
| - name: Cache Flutter SDK | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.pub-cache | |
| ${{ runner.tool_cache }}/flutter | |
| key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-flutter- | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: "3.32.2" | |
| channel: "stable" | |
| cache: true | |
| - name: Cache Pub dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.pub-cache | |
| .dart_tool | |
| key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pub- | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Cache Gradle dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| ~/.android/build-cache | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Run semantic-release (dry-run to get version) | |
| id: semantic_release_dry | |
| run: | | |
| # Run semantic-release in dry-run mode to get the next version | |
| NEXT_VERSION=$(npx semantic-release --dry-run --no-ci | grep -oP 'The next release version is \K[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?' || echo "") | |
| if [ -n "$NEXT_VERSION" ]; then | |
| echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT | |
| echo "has_release=true" >> $GITHUB_OUTPUT | |
| # Update pubspec.yaml with the new version | |
| sed -i "s/^version: .*/version: $NEXT_VERSION/" pubspec.yaml | |
| echo "Updated pubspec.yaml version to: $NEXT_VERSION" | |
| else | |
| echo "has_release=false" >> $GITHUB_OUTPUT | |
| echo "No release will be created" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup signing | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' | |
| run: | | |
| echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/release-key.jks | |
| echo "storeFile=release-key.jks" > key.properties | |
| echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> key.properties | |
| echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> key.properties | |
| echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> key.properties | |
| - name: Build signed APK | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' | |
| run: flutter build apk --release | |
| - name: Build App Bundle | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' | |
| continue-on-error: true | |
| run: flutter build appbundle --release | |
| - name: Prepare release assets | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' | |
| run: | | |
| mkdir -p release-files | |
| VERSION=${{ steps.semantic_release_dry.outputs.next_version }} | |
| # Copy APK if exists | |
| if [ -f "build/app/outputs/flutter-apk/app-release.apk" ]; then | |
| cp build/app/outputs/flutter-apk/app-release.apk release-files/readeck-app-${VERSION}.apk | |
| fi | |
| # Copy AAB if exists | |
| if [ -f "build/app/outputs/bundle/release/app-release.aab" ]; then | |
| cp build/app/outputs/bundle/release/app-release.aab release-files/readeck-app-${VERSION}.aab | |
| fi | |
| - name: Clean up signing files | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' && env.KEYSTORE_BASE64 != '' | |
| run: | | |
| rm -f android/app/release-key.jks | |
| rm -f android/key.properties | |
| env: | |
| KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} | |
| - name: Run semantic-release | |
| if: steps.semantic_release_dry.outputs.has_release == 'true' | |
| run: npx semantic-release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |