Build All (bundle) #28
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 All (bundle) | |
| on: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| env: | |
| APP_NAME: MiruShin | |
| PUBSPEC_APP_NAME: mirushin | |
| LINUX_APP_ID: com.emp0ry.mirushin | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| build-android: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Java (17) | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| - name: Setup Flutter (stable) | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Flutter pub get | |
| run: flutter pub get | |
| - name: Build APK (release) | |
| run: flutter build apk --release | |
| - name: Read version from pubspec.yaml | |
| id: ver | |
| shell: bash | |
| run: | | |
| VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}' | cut -d'+' -f1) | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Rename APK | |
| id: apk | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| SRC_APK=$(find build/app/outputs/flutter-apk -maxdepth 1 -type f -name '*.apk' | head -n 1) | |
| if [ -z "$SRC_APK" ]; then | |
| echo "ERROR: no APK found in build/app/outputs/flutter-apk" | |
| exit 1 | |
| fi | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| DEST_APK="${APP_NAME}-android-v${VERSION}.apk" | |
| cp "$SRC_APK" "$DEST_APK" | |
| echo "apk_path=$DEST_APK" >> "$GITHUB_OUTPUT" | |
| - name: Upload Android artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-android | |
| path: ${{ steps.apk.outputs.apk_path }} | |
| build-linux: | |
| runs-on: ubuntu-latest | |
| # Pin the MDK SDK (the native libmdk.so fvp bundles) to a stable, tagged | |
| # release. By default fvp downloads the SourceForge *nightly* at build | |
| # time (fvp cmake/deps.cmake), so the bundled libmdk silently changes day | |
| # to day even though the fvp package version is fixed. A June 1 nightly | |
| # regressed and crashes on playback (SIGSEGV at 0x0 in a libmdk | |
| # FrameReader/MediaIO::createForProtocol worker thread). Scoped to this job | |
| # so Android/Windows/macOS keep their own mdk handling. | |
| env: | |
| FVP_DEPS_URL: https://github.com/wang-bin/mdk-sdk/releases/latest/download | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Flutter (stable) | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Install Linux build deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev \ | |
| libfuse2 libglib2.0-0 libsecret-1-dev libpulse0 python3-pil | |
| # libmdk ships its OWN FFmpeg (libffmpeg.so.8, bundled below), so the | |
| # host does not need the system ffmpeg/VA-API stack. libpulse0 stays | |
| # because libmdk DT_NEEDs libpulse.so.0 and linuxdeploy bundles it. | |
| - name: Flutter pub get | |
| run: flutter pub get | |
| - name: Force fresh pinned MDK SDK | |
| run: | | |
| # fvp's cmake/deps.cmake skips re-downloading libmdk if an mdk-sdk is | |
| # already extracted in its package dir. Because ~/.pub-cache can be | |
| # cached between runs, a previously-downloaded (broken nightly) libmdk | |
| # could otherwise persist and silently ignore FVP_DEPS_URL. Delete any | |
| # cached/extracted mdk-sdk so the pinned stable SDK is always fetched. | |
| find "$HOME/.pub-cache" -type d -path "*fvp*/linux/mdk-sdk" -prune -exec rm -rf {} + 2>/dev/null || true | |
| find "$HOME/.pub-cache" -type f -path "*fvp*/linux/mdk-sdk-*.tar.xz*" -delete 2>/dev/null || true | |
| echo "Cleared cached mdk-sdk; build will fetch FVP_DEPS_URL=$FVP_DEPS_URL" | |
| - name: Strip Linux MediaKit plugin | |
| run: bash .github/scripts/strip-linux-media-kit.sh | |
| - name: Build Linux (release) | |
| run: flutter build linux --release --no-pub | |
| - name: Read version from pubspec.yaml | |
| id: ver | |
| shell: bash | |
| run: | | |
| VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}' | cut -d'+' -f1) | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Create tar.gz bundle | |
| id: tgz | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| OUT_DIR="build/linux/x64/release/bundle" | |
| if [ ! -d "$OUT_DIR" ]; then | |
| echo "ERROR: bundle not found at $OUT_DIR" | |
| ls -la build/linux/x64/release || true | |
| exit 1 | |
| fi | |
| TGZ="${APP_NAME}-linux-v${VERSION}.tar.gz" | |
| tar -C "$OUT_DIR" -czf "$TGZ" . | |
| echo "tgz_path=$TGZ" >> "$GITHUB_OUTPUT" | |
| - name: Build AppImage | |
| id: appimage | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| OUT_DIR="build/linux/x64/release/bundle" | |
| curl -L -o linuxdeploy-x86_64.AppImage \ | |
| https://github.com/linuxdeploy/linuxdeploy/releases/latest/download/linuxdeploy-x86_64.AppImage | |
| curl -L -o linuxdeploy-plugin-gtk.sh \ | |
| https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh | |
| chmod +x linuxdeploy-x86_64.AppImage | |
| chmod +x linuxdeploy-plugin-gtk.sh | |
| rm -rf AppDir | |
| mkdir -p AppDir/usr/bin | |
| cp -r "$OUT_DIR/"* AppDir/usr/bin/ | |
| APP_BIN="AppDir/usr/bin/${PUBSPEC_APP_NAME}" | |
| if [ ! -x "$APP_BIN" ]; then | |
| APP_BIN="$(find AppDir/usr/bin -maxdepth 1 -type f -executable | head -n 1)" | |
| fi | |
| if [ -z "$APP_BIN" ]; then | |
| echo "ERROR: cannot find main executable in AppDir/usr/bin" | |
| ls -la AppDir/usr/bin || true | |
| exit 1 | |
| fi | |
| mkdir -p AppDir/usr/share/applications | |
| cat > "AppDir/usr/share/applications/${LINUX_APP_ID}.desktop" <<EOAPP | |
| [Desktop Entry] | |
| Type=Application | |
| Name=${APP_NAME} | |
| Exec=$(basename "$APP_BIN") | |
| Icon=${LINUX_APP_ID} | |
| Categories=AudioVideo; | |
| StartupWMClass=${APP_NAME} | |
| EOAPP | |
| mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps | |
| ICON_PATH="AppDir/usr/share/icons/hicolor/256x256/apps/${LINUX_APP_ID}.png" | |
| if [ -f "assets/icons/logo.png" ]; then | |
| ICON_SOURCE="assets/icons/logo.png" | |
| elif [ -f "linux/runner/resources/logo.png" ]; then | |
| ICON_SOURCE="linux/runner/resources/logo.png" | |
| else | |
| echo "ERROR: no app logo found at assets/icons/logo.png or linux/runner/resources/logo.png" | |
| exit 1 | |
| fi | |
| python3 -c "from PIL import Image; Image.open('$ICON_SOURCE').resize((256, 256), Image.LANCZOS).save('$ICON_PATH')" | |
| if [ ! -f "$ICON_PATH" ]; then | |
| echo "ERROR: icon was not created at $ICON_PATH" | |
| exit 1 | |
| fi | |
| export LINUXDEPLOY=./linuxdeploy-x86_64.AppImage | |
| export LINUXDEPLOY_PLUGIN_GTK=./linuxdeploy-plugin-gtk.sh | |
| # Phase 1: let linuxdeploy populate the AppDir (deps, AppRun, desktop, | |
| # icon, GTK) but DO NOT package yet (no --output). | |
| ./linuxdeploy-x86_64.AppImage \ | |
| --appdir AppDir \ | |
| --executable "$APP_BIN" \ | |
| --desktop-file "AppDir/usr/share/applications/${LINUX_APP_ID}.desktop" \ | |
| --icon-file "$ICON_PATH" \ | |
| --plugin gtk | |
| # Phase 2: libmdk dlopens its FFmpeg backend (libffmpeg.so.*) + codec | |
| # plugins at RUNTIME — they are NOT in libmdk's DT_NEEDED graph, so | |
| # linuxdeploy never bundles them and playback SIGSEGVs the instant it | |
| # starts (MediaIO::create -> NULL FFmpeg I/O vtable). Physically copy | |
| # the whole mdk runtime into usr/lib (where linuxdeploy put libmdk) so | |
| # dlopen finds it via the AppRun's LD_LIBRARY_PATH. | |
| MDK_LIB_DIR="$(dirname "$APP_BIN")/lib" | |
| mkdir -p AppDir/usr/lib | |
| copied=0 | |
| for so in "$MDK_LIB_DIR"/libffmpeg.so* "$MDK_LIB_DIR"/libmdk*.so* "$MDK_LIB_DIR"/libc++.so*; do | |
| [ -e "$so" ] || continue | |
| cp -aP "$so" AppDir/usr/lib/ && echo "Bundled $(basename "$so")" && copied=1 | |
| done | |
| if [ "$copied" != 1 ]; then | |
| echo "ERROR: no libmdk runtime libs found in $MDK_LIB_DIR" | |
| ls -la "$MDK_LIB_DIR" || true | |
| exit 1 | |
| fi | |
| # Phase 3: package the AppDir verbatim. appimagetool copies the tree | |
| # as-is, so the dlopen-only libs we just placed cannot be stripped. | |
| curl -L -o appimagetool-x86_64.AppImage \ | |
| https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage | |
| chmod +x appimagetool-x86_64.AppImage | |
| FINAL="${APP_NAME}-linux-v${VERSION}.AppImage" | |
| ARCH=x86_64 ./appimagetool-x86_64.AppImage --no-appstream AppDir "$FINAL" | |
| chmod +x "$FINAL" | |
| # Guard: fail the build (don't ship) if libffmpeg didn't make it in. | |
| rm -rf squashfs-root | |
| "./$FINAL" --appimage-extract >/dev/null 2>&1 || true | |
| if ! ls squashfs-root/usr/lib/libffmpeg.so* >/dev/null 2>&1; then | |
| echo "ERROR: libffmpeg.so missing from AppImage — playback would crash." | |
| find squashfs-root -name 'libmdk*' -o -name 'libffmpeg*' || true | |
| exit 1 | |
| fi | |
| echo "Verified: $(ls squashfs-root/usr/lib/libffmpeg.so*) bundled in AppImage" | |
| rm -rf squashfs-root | |
| echo "appimage_path=$FINAL" >> "$GITHUB_OUTPUT" | |
| - name: Build .deb package | |
| id: deb | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| OUT_DIR="build/linux/x64/release/bundle" | |
| PKG="${PUBSPEC_APP_NAME}" | |
| DEB_DIR="deb/${PKG}" | |
| # Install the whole bundle under /usr/lib/<app> so the executable's | |
| # RPATH ($ORIGIN/lib) finds every bundled lib — including libmdk and | |
| # its dlopen'd libffmpeg.so.8, which sit together in lib/. | |
| rm -rf deb | |
| mkdir -p "$DEB_DIR/DEBIAN" \ | |
| "$DEB_DIR/usr/lib/${PKG}" \ | |
| "$DEB_DIR/usr/bin" \ | |
| "$DEB_DIR/usr/share/applications" \ | |
| "$DEB_DIR/usr/share/icons/hicolor/256x256/apps" | |
| cp -r "$OUT_DIR/"* "$DEB_DIR/usr/lib/${PKG}/" | |
| ln -s "/usr/lib/${PKG}/${PKG}" "$DEB_DIR/usr/bin/${PKG}" | |
| cat > "$DEB_DIR/usr/share/applications/${LINUX_APP_ID}.desktop" <<EOF | |
| [Desktop Entry] | |
| Type=Application | |
| Name=${APP_NAME} | |
| Exec=${PKG} | |
| Icon=${LINUX_APP_ID} | |
| Categories=AudioVideo; | |
| StartupWMClass=${APP_NAME} | |
| EOF | |
| # Icon: render several sizes into the hicolor theme + a pixmaps | |
| # fallback so every desktop environment finds it. | |
| if [ -f "assets/icons/logo.png" ]; then ICON_SRC="assets/icons/logo.png" | |
| elif [ -f "linux/runner/resources/logo.png" ]; then ICON_SRC="linux/runner/resources/logo.png" | |
| else echo "ERROR: no source logo for .deb icon"; exit 1; fi | |
| mkdir -p "$DEB_DIR/usr/share/pixmaps" | |
| for sz in 16 32 48 64 128 256 512; do | |
| d="$DEB_DIR/usr/share/icons/hicolor/${sz}x${sz}/apps" | |
| mkdir -p "$d" | |
| python3 -c "from PIL import Image; Image.open('$ICON_SRC').convert('RGBA').resize(($sz,$sz), Image.LANCZOS).save('$d/${LINUX_APP_ID}.png')" | |
| done | |
| cp "$DEB_DIR/usr/share/icons/hicolor/256x256/apps/${LINUX_APP_ID}.png" \ | |
| "$DEB_DIR/usr/share/pixmaps/${LINUX_APP_ID}.png" | |
| # Refresh icon + desktop caches on install/remove so the launcher | |
| # shows the icon immediately. | |
| cat > "$DEB_DIR/DEBIAN/postinst" <<'EOF' | |
| #!/bin/sh | |
| set -e | |
| if command -v gtk-update-icon-cache >/dev/null 2>&1; then | |
| gtk-update-icon-cache -f -t /usr/share/icons/hicolor >/dev/null 2>&1 || true | |
| fi | |
| if command -v update-desktop-database >/dev/null 2>&1; then | |
| update-desktop-database -q /usr/share/applications >/dev/null 2>&1 || true | |
| fi | |
| exit 0 | |
| EOF | |
| cp "$DEB_DIR/DEBIAN/postinst" "$DEB_DIR/DEBIAN/postrm" | |
| chmod 0755 "$DEB_DIR/DEBIAN/postinst" "$DEB_DIR/DEBIAN/postrm" | |
| INSTALLED_KB=$(du -sk "$DEB_DIR/usr" | cut -f1) | |
| cat > "$DEB_DIR/DEBIAN/control" <<EOF | |
| Package: ${PKG} | |
| Version: ${VERSION} | |
| Section: video | |
| Priority: optional | |
| Architecture: amd64 | |
| Maintainer: emp0ry <avagyanerik13@gmail.com> | |
| Installed-Size: ${INSTALLED_KB} | |
| Depends: libgtk-3-0, libglib2.0-0, libsecret-1-0, libpulse0, libgl1, libegl1 | |
| Description: ${APP_NAME} anime player | |
| Cross-platform anime streaming/player app. | |
| EOF | |
| DEB="${APP_NAME}-linux-v${VERSION}.deb" | |
| dpkg-deb --build --root-owner-group "$DEB_DIR" "$DEB" | |
| echo "deb_path=$DEB" >> "$GITHUB_OUTPUT" | |
| dpkg-deb -c "$DEB" | grep -E 'libffmpeg|libmdk\.so' || true | |
| - name: Upload Linux artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-linux | |
| path: | | |
| ${{ steps.appimage.outputs.appimage_path }} | |
| ${{ steps.tgz.outputs.tgz_path }} | |
| ${{ steps.deb.outputs.deb_path }} | |
| build-windows: | |
| runs-on: windows-2025-vs2026 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Flutter (stable) | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: false | |
| - name: Flutter pub get | |
| run: flutter pub get | |
| - name: Build Windows (release) | |
| env: | |
| FVP_DEPS_URL: https://github.com/wang-bin/mdk-sdk/releases/latest/download | |
| run: flutter build windows --release | |
| - name: Read version from pubspec.yaml | |
| id: ver | |
| shell: pwsh | |
| run: | | |
| $v = (Get-Content "pubspec.yaml" | Where-Object { $_ -match '^version:' } | ForEach-Object { | |
| ($_ -split ':')[1].Trim().Split(' ')[0] | |
| } | Select-Object -First 1) | |
| if (-not $v) { throw "Version not found in pubspec.yaml" } | |
| $v = $v.Split('+')[0] | |
| "version=$v" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| - name: Create ZIP from Release folder contents | |
| id: zip | |
| shell: pwsh | |
| run: | | |
| $sourceDir = "build/windows/x64/runner/Release" | |
| if (-not (Test-Path $sourceDir)) { throw "Source folder not found: $sourceDir" } | |
| $version = "${{ steps.ver.outputs.version }}" | |
| $zipFile = "${{ env.APP_NAME }}-windows-v$version-portable.zip" | |
| if (Test-Path $zipFile) { Remove-Item $zipFile -Force } | |
| Compress-Archive -Path (Join-Path $sourceDir '*') -DestinationPath $zipFile -Force | |
| "zip_path=$zipFile" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| - name: Build Inno Setup installer | |
| id: installer | |
| shell: pwsh | |
| run: | | |
| $iscc = $null | |
| $candidates = @( | |
| "C:\Program Files (x86)\Inno Setup 6\ISCC.exe", | |
| "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" | |
| ) | |
| foreach ($c in $candidates) { | |
| if (Test-Path $c) { $iscc = $c; break } | |
| } | |
| if (-not $iscc) { | |
| choco install innosetup --no-progress -y | |
| $iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" | |
| } | |
| $version = "${{ steps.ver.outputs.version }}" | |
| $sourceDir = (Resolve-Path "build/windows/x64/runner/Release").Path | |
| & "$iscc" ` | |
| "/DMyAppVersion=$version" ` | |
| "/DMySourceDir=$sourceDir" ` | |
| "/O." ` | |
| "windows\installer\mirushin.iss" | |
| if ($LASTEXITCODE -ne 0) { throw "Inno Setup compilation failed (exit $LASTEXITCODE)" } | |
| $exeFile = "${{ env.APP_NAME }}-windows-v$version-setup.exe" | |
| "installer_path=$exeFile" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| - name: Upload Windows artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-windows | |
| path: | | |
| ${{ steps.zip.outputs.zip_path }} | |
| ${{ steps.installer.outputs.installer_path }} | |
| build-macos-ios: | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Flutter (stable) | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Flutter pub get | |
| run: flutter pub get | |
| - name: Pre-cache mdk SDK (bypass unreliable SourceForge nightly) | |
| run: | | |
| set -e | |
| MDK_SF_URL="https://sourceforge.net/projects/mdk-sdk/files/nightly/mdk-sdk-apple.tar.xz" | |
| MDK_GH_URL="https://github.com/wang-bin/mdk-sdk/releases/latest/download/mdk-sdk-apple.tar.xz" | |
| CACHE_HASH=$(ruby -rdigest -e 'puts Digest::MD5.hexdigest({:http=>ARGV[0]}.to_s)' "$MDK_SF_URL") | |
| CACHE_DIR="$HOME/Library/Caches/CocoaPods/Pods/External/mdk/$CACHE_HASH" | |
| if [ ! -d "$CACHE_DIR" ]; then | |
| echo "Downloading mdk SDK from GitHub releases..." | |
| mkdir -p "$CACHE_DIR" | |
| curl -fL "$MDK_GH_URL" -o /tmp/mdk-sdk-apple.tar.xz | |
| tar xf /tmp/mdk-sdk-apple.tar.xz -C "$CACHE_DIR" | |
| rm -f /tmp/mdk-sdk-apple.tar.xz | |
| echo "Cached at $CACHE_DIR" | |
| fi | |
| - name: Prepare iOS no-codesign config | |
| shell: bash | |
| run: | | |
| { | |
| echo "" | |
| echo "CODE_SIGN_ENTITLEMENTS=" | |
| echo "DEVELOPMENT_TEAM=" | |
| echo "PROVISIONING_PROFILE_SPECIFIER=" | |
| echo "CODE_SIGN_STYLE=Manual" | |
| } >> ios/Flutter/Release.xcconfig | |
| - name: Build iOS (release, no codesign) | |
| run: flutter build ios --release --no-codesign | |
| - name: Read version from pubspec.yaml | |
| id: ver | |
| shell: bash | |
| run: | | |
| VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}' | cut -d'+' -f1) | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Create IPA | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| APP_PATH="build/ios/iphoneos/Runner.app" | |
| if [ ! -d "$APP_PATH" ]; then | |
| echo "ERROR: iOS app not found at $APP_PATH" | |
| ls -la build/ios/iphoneos || true | |
| exit 1 | |
| fi | |
| rm -rf Payload | |
| mkdir -p Payload | |
| cp -R "$APP_PATH" Payload/ | |
| zip -r "${APP_NAME}-ios-v${VERSION}.ipa" Payload | |
| - name: Build macOS (release) | |
| run: flutter build macos --release | |
| - name: Package DMG (drag & drop) | |
| shell: bash | |
| run: bash .github/scripts/package-macos-dmg.sh | |
| - name: Upload iOS artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-ios | |
| path: MiruShin-ios-v*.ipa | |
| - name: Upload macOS artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-macos | |
| path: MiruShin-macos-v*.dmg | |
| package-all: | |
| runs-on: ubuntu-latest | |
| needs: [build-android, build-linux, build-windows, build-macos-ios] | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Show bundled files | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| find dist -maxdepth 1 -type f | sort | |
| - name: Upload bundle artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: MiruShin-all | |
| path: dist/* |