# DEPLOYMENT_PLAN §5 — 태그(v*) 푸시 → 전 아티팩트 매트릭스 빌드 → Draft Release # D1: test → Windows 설치자 · D2: Android APK · D3: Linux tar.gz # D4(macOS 서명·공증)/D5(iOS TestFlight)는 Apple Developer Program 시크릿 등록 후 활성화. name: release on: push: tags: ["v*"] workflow_dispatch: # 수동 실행(리허설) env: DOTNET_NOLOGO: true DOTNET_CLI_TELEMETRY_OPTOUT: true jobs: # ── 관문: 전 플랫폼 빌드 전에 단위+E2E 통과 ── test: runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: | 8.0.x 10.0.x - name: dotnet test run: dotnet test VideoDownloader.Tests -c Release # ── Windows 설치자 (x64 / arm64 교차 publish + Inno Setup) ── windows: needs: test runs-on: windows-latest strategy: matrix: arch: [x64, arm64] steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - name: Inno Setup 설치 run: choco install innosetup -y --no-progress - name: 버전 결정 (태그 v1.2.3 → 1.2.3) shell: pwsh run: | $v = "${{ github.ref_name }}".TrimStart("v") if ($v -notmatch '^\d+\.\d+\.\d+') { $v = "0.0.0" } # workflow_dispatch 리허설 "APP_VERSION=$v" >> $env:GITHUB_ENV - name: publish + 설치자 shell: pwsh run: ./build/publish.ps1 -Config Release -Version $env:APP_VERSION -Archs ${{ matrix.arch }} - uses: actions/upload-artifact@v4 with: name: win-${{ matrix.arch }} path: out/MediaBrowser-Setup-${{ matrix.arch }}.exe # ── Linux 셸 (tar.gz self-contained — Avalonia + Cli) ── linux: needs: test strategy: matrix: include: - { os: ubuntu-latest, rid: linux-x64 } - { os: ubuntu-24.04-arm, rid: linux-arm64 } runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: | 8.0.x 10.0.x - name: publish (Cli + Avalonia) run: | dotnet publish VideoDownloader.Cli -c Release -r ${{ matrix.rid }} --self-contained -o out/cli-${{ matrix.rid }} dotnet publish VideoDownloader.Avalonia -c Release -r ${{ matrix.rid }} --self-contained -o out/avalonia-${{ matrix.rid }} tar -C out -czf out/mediabrowser-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} - uses: actions/upload-artifact@v4 with: name: ${{ matrix.rid }} path: out/mediabrowser-${{ matrix.rid }}.tar.gz # ── macOS 셸 (tar.gz — D4 서명·공증은 Developer ID 시크릿 등록 후 확장) ── macos: needs: test strategy: matrix: include: - { os: macos-latest, rid: osx-arm64 } - { os: macos-13, rid: osx-x64 } runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: | 8.0.x 10.0.x - name: publish (Cli + Avalonia) run: | dotnet publish VideoDownloader.Cli -c Release -r ${{ matrix.rid }} --self-contained -o out/cli-${{ matrix.rid }} dotnet publish VideoDownloader.Avalonia -c Release -r ${{ matrix.rid }} --self-contained -o out/avalonia-${{ matrix.rid }} tar -C out -czf out/mediabrowser-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} # D4: MACOS_P12/KEYCHAIN_PASS/NOTARY_PROFILE 시크릿 등록 시 codesign+notarytool+DMG 스텝 추가 - uses: actions/upload-artifact@v4 with: name: ${{ matrix.rid }} path: out/mediabrowser-${{ matrix.rid }}.tar.gz # ── Android APK (D2 — 서명 키스토어 시크릿 없으면 미서명 APK) ── android: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: microsoft java-version: "21" - uses: actions/setup-dotnet@v4 with: dotnet-version: | 8.0.x 10.0.x - name: MAUI 워크로드 run: dotnet workload install maui-android - name: publish APK env: ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE }} ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} ANDROID_KEY_PASS: ${{ secrets.ANDROID_KEY_PASS }} run: | SIGN_ARGS="" if [ -n "$ANDROID_KEYSTORE_B64" ]; then echo "$ANDROID_KEYSTORE_B64" | base64 -d > vd.keystore SIGN_ARGS="-p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$PWD/vd.keystore -p:AndroidSigningKeyAlias=$ANDROID_KEY_ALIAS -p:AndroidSigningKeyPass=$ANDROID_KEY_PASS -p:AndroidSigningStorePass=$ANDROID_KEY_PASS" else echo "::notice::ANDROID_KEYSTORE 시크릿 없음 — 미서명 APK 생성" fi dotnet publish VideoDownloader.Mobile -f net10.0-android -c Release \ -p:AndroidPackageFormat=apk -p:RuntimeIdentifiers=android-arm64 $SIGN_ARGS \ -o out/android - uses: actions/upload-artifact@v4 with: name: android-apk path: out/android/*-Signed.apk if-no-files-found: warn # ── iOS TestFlight (D5 — Apple Developer Program 가입 후 저장소 변수 ENABLE_IOS=true 로 활성화) ── ios: if: vars.ENABLE_IOS == 'true' needs: test runs-on: macos-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: 10.0.x - name: MAUI 워크로드 run: dotnet workload install maui-ios - name: publish ipa (배포 인증서/프로비저닝 시크릿 필요) run: | dotnet publish VideoDownloader.Mobile -f net10.0-ios -c Release \ -p:ArchiveOnBuild=true -p:CodesignKey="${{ secrets.IOS_SIGNING_KEY }}" \ -p:CodesignProvision="${{ secrets.IOS_PROVISION }}" -o out/ios - uses: actions/upload-artifact@v4 with: name: ios-ipa path: out/ios/**/*.ipa # ── Draft Release (QA 후 수동 Publish 승격) ── release: if: startsWith(github.ref, 'refs/tags/v') needs: [test, windows, linux, macos, android] runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/download-artifact@v4 with: path: dist merge-multiple: true - uses: softprops/action-gh-release@v2 with: draft: true files: dist/**