name: Release on: push: tags: - "v*" permissions: contents: read jobs: build-cli: name: Build CLI for ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: matrix: include: - target: x86_64-apple-darwin os: macos-latest - target: aarch64-apple-darwin os: macos-latest - target: x86_64-unknown-linux-gnu os: ubuntu-latest - target: aarch64-unknown-linux-gnu os: ubuntu-24.04-arm - target: x86_64-pc-windows-msvc os: windows-latest - target: aarch64-pc-windows-msvc os: windows-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install Rust uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable with: targets: ${{ matrix.target }} - name: Build run: cargo build --release --features replaygain --target ${{ matrix.target }} env: RUSTFLAGS: ${{ contains(matrix.target, 'windows') && '-C target-feature=+crt-static' || '' }} - name: Upload artifact (Unix) if: runner.os != 'Windows' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: mp3rgain-${{ matrix.target }} path: target/${{ matrix.target }}/release/mp3rgain - name: Upload artifact (Windows) if: runner.os == 'Windows' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: mp3rgain-${{ matrix.target }} path: target/${{ matrix.target }}/release/mp3rgain.exe build-gui: name: Build GUI for ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: matrix: include: - target: x86_64-apple-darwin os: macos-latest - target: aarch64-apple-darwin os: macos-latest - target: x86_64-unknown-linux-gnu os: ubuntu-latest - target: aarch64-unknown-linux-gnu os: ubuntu-24.04-arm - target: x86_64-pc-windows-msvc os: windows-latest - target: aarch64-pc-windows-msvc os: windows-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install Rust uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable with: targets: ${{ matrix.target }} - name: Install Linux dependencies if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y libxkbcommon-dev libwayland-dev libgtk-3-dev - name: Build GUI run: cargo build --release --manifest-path mp3rgui/Cargo.toml --target ${{ matrix.target }} env: RUSTFLAGS: ${{ contains(matrix.target, 'windows') && '-C target-feature=+crt-static' || '' }} - name: Upload artifact (Unix) if: runner.os != 'Windows' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: mp3rgui-${{ matrix.target }} path: mp3rgui/target/${{ matrix.target }}/release/mp3rgui - name: Upload artifact (Windows) if: runner.os == 'Windows' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: mp3rgui-${{ matrix.target }} path: mp3rgui/target/${{ matrix.target }}/release/mp3rgui.exe build-installer: name: Build Windows installer needs: build-gui runs-on: windows-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Download GUI Windows binaries uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: pattern: mp3rgui-*-pc-windows-msvc path: artifacts - name: Build installer shell: bash env: TAG: ${{ github.ref_name }} run: | scripts/build-windows-installer.sh \ "${TAG#v}" \ "mp3rgui-${TAG}-windows-setup" \ artifacts/mp3rgui-x86_64-pc-windows-msvc/mp3rgui.exe \ artifacts/mp3rgui-aarch64-pc-windows-msvc/mp3rgui.exe - name: Upload installer uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: mp3rgui-windows-installer path: target/windows-installer/mp3rgui-*-windows-setup.exe release: name: Create Release needs: [build-cli, build-gui, build-installer] runs-on: macos-latest permissions: contents: write outputs: version: ${{ steps.version.outputs.version }} windows_x64_sha256: ${{ steps.checksums.outputs.windows_x64_sha256 }} windows_arm64_sha256: ${{ steps.checksums.outputs.windows_arm64_sha256 }} macos_sha256: ${{ steps.checksums.outputs.macos_sha256 }} gui_macos_dmg_sha256: ${{ steps.checksums.outputs.gui_macos_dmg_sha256 }} gui_windows_x64_sha256: ${{ steps.checksums.outputs.gui_windows_x64_sha256 }} gui_windows_arm64_sha256: ${{ steps.checksums.outputs.gui_windows_arm64_sha256 }} gui_windows_setup_sha256: ${{ steps.checksums.outputs.gui_windows_setup_sha256 }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Get version id: version run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT - name: Download all artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: artifacts - name: Create universal macOS binary run: | mkdir -p dist lipo -create \ artifacts/mp3rgain-x86_64-apple-darwin/mp3rgain \ artifacts/mp3rgain-aarch64-apple-darwin/mp3rgain \ -output dist/mp3rgain chmod +x dist/mp3rgain - name: Create macOS tarball env: TAG: ${{ github.ref_name }} run: | cd dist tar -czvf "mp3rgain-${TAG}-macos-universal.tar.gz" mp3rgain shasum -a 256 "mp3rgain-${TAG}-macos-universal.tar.gz" > "mp3rgain-${TAG}-macos-universal.tar.gz.sha256" - name: Create Linux x86_64 tarball env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgain-x86_64-unknown-linux-gnu chmod +x mp3rgain tar -czvf "../../dist/mp3rgain-${TAG}-linux-x86_64.tar.gz" mp3rgain cd ../../dist shasum -a 256 "mp3rgain-${TAG}-linux-x86_64.tar.gz" > "mp3rgain-${TAG}-linux-x86_64.tar.gz.sha256" - name: Create Linux ARM64 tarball env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgain-aarch64-unknown-linux-gnu chmod +x mp3rgain tar -czvf "../../dist/mp3rgain-${TAG}-linux-arm64.tar.gz" mp3rgain cd ../../dist shasum -a 256 "mp3rgain-${TAG}-linux-arm64.tar.gz" > "mp3rgain-${TAG}-linux-arm64.tar.gz.sha256" - name: Create Windows x86_64 zip env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgain-x86_64-pc-windows-msvc zip "../../dist/mp3rgain-${TAG}-windows-x86_64.zip" mp3rgain.exe cd ../../dist shasum -a 256 "mp3rgain-${TAG}-windows-x86_64.zip" > "mp3rgain-${TAG}-windows-x86_64.zip.sha256" - name: Create Windows ARM64 zip env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgain-aarch64-pc-windows-msvc zip "../../dist/mp3rgain-${TAG}-windows-arm64.zip" mp3rgain.exe cd ../../dist shasum -a 256 "mp3rgain-${TAG}-windows-arm64.zip" > "mp3rgain-${TAG}-windows-arm64.zip.sha256" - name: Create GUI macOS .app bundle env: TAG: ${{ github.ref_name }} VERSION: ${{ steps.version.outputs.version }} run: | # Create universal binary lipo -create \ artifacts/mp3rgui-x86_64-apple-darwin/mp3rgui \ artifacts/mp3rgui-aarch64-apple-darwin/mp3rgui \ -output dist/mp3rgui chmod +x dist/mp3rgui # Create .app bundle structure APP="dist/mp3rgui.app" mkdir -p "${APP}/Contents/MacOS" mkdir -p "${APP}/Contents/Resources" mv dist/mp3rgui "${APP}/Contents/MacOS/mp3rgui" cp mp3rgui/icons/mp3rgui.icns "${APP}/Contents/Resources/mp3rgui.icns" sed "s/__VERSION__/${VERSION}/g" packages/macos/Info.plist > "${APP}/Contents/Info.plist" # Create DMG hdiutil create -volname "mp3rgui" -srcfolder "${APP}" -ov -format UDZO "dist/mp3rgui-${TAG}-macos-universal.dmg" cd dist shasum -a 256 "mp3rgui-${TAG}-macos-universal.dmg" > "mp3rgui-${TAG}-macos-universal.dmg.sha256" # Also create tarball for backward compatibility tar -czvf "mp3rgui-${TAG}-macos-universal.tar.gz" mp3rgui.app shasum -a 256 "mp3rgui-${TAG}-macos-universal.tar.gz" > "mp3rgui-${TAG}-macos-universal.tar.gz.sha256" rm -rf mp3rgui.app - name: Create GUI Linux x86_64 tarball env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgui-x86_64-unknown-linux-gnu chmod +x mp3rgui tar -czvf "../../dist/mp3rgui-${TAG}-linux-x86_64.tar.gz" mp3rgui - name: Create GUI Linux ARM64 tarball env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgui-aarch64-unknown-linux-gnu chmod +x mp3rgui tar -czvf "../../dist/mp3rgui-${TAG}-linux-arm64.tar.gz" mp3rgui - name: Create GUI Windows x86_64 zip env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgui-x86_64-pc-windows-msvc zip "../../dist/mp3rgui-${TAG}-windows-x86_64.zip" mp3rgui.exe cd ../../dist shasum -a 256 "mp3rgui-${TAG}-windows-x86_64.zip" > "mp3rgui-${TAG}-windows-x86_64.zip.sha256" - name: Create GUI Windows ARM64 zip env: TAG: ${{ github.ref_name }} run: | cd artifacts/mp3rgui-aarch64-pc-windows-msvc zip "../../dist/mp3rgui-${TAG}-windows-arm64.zip" mp3rgui.exe cd ../../dist shasum -a 256 "mp3rgui-${TAG}-windows-arm64.zip" > "mp3rgui-${TAG}-windows-arm64.zip.sha256" - name: Collect GUI Windows installer env: TAG: ${{ github.ref_name }} run: | cp "artifacts/mp3rgui-windows-installer/mp3rgui-${TAG}-windows-setup.exe" dist/ # Also publish under a version-free name. GitHub serves # /releases/latest/download/ only when the asset name is # identical in every release, so this is what makes a permanent # "download the current installer" link possible. cp "dist/mp3rgui-${TAG}-windows-setup.exe" dist/mp3rgui-windows-setup.exe cd dist shasum -a 256 "mp3rgui-${TAG}-windows-setup.exe" > "mp3rgui-${TAG}-windows-setup.exe.sha256" shasum -a 256 mp3rgui-windows-setup.exe > mp3rgui-windows-setup.exe.sha256 - name: Extract checksums id: checksums env: TAG: ${{ github.ref_name }} run: | echo "windows_x64_sha256=$(cat "dist/mp3rgain-${TAG}-windows-x86_64.zip.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "windows_arm64_sha256=$(cat "dist/mp3rgain-${TAG}-windows-arm64.zip.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "macos_sha256=$(cat "dist/mp3rgain-${TAG}-macos-universal.tar.gz.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "gui_macos_dmg_sha256=$(cat "dist/mp3rgui-${TAG}-macos-universal.dmg.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "gui_windows_x64_sha256=$(cat "dist/mp3rgui-${TAG}-windows-x86_64.zip.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "gui_windows_arm64_sha256=$(cat "dist/mp3rgui-${TAG}-windows-arm64.zip.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT echo "gui_windows_setup_sha256=$(cat "dist/mp3rgui-${TAG}-windows-setup.exe.sha256" | awk '{print $1}')" >> $GITHUB_OUTPUT - name: Create Release uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v2 with: files: | dist/mp3rgain-${{ github.ref_name }}-macos-universal.tar.gz dist/mp3rgain-${{ github.ref_name }}-macos-universal.tar.gz.sha256 dist/mp3rgain-${{ github.ref_name }}-linux-x86_64.tar.gz dist/mp3rgain-${{ github.ref_name }}-linux-x86_64.tar.gz.sha256 dist/mp3rgain-${{ github.ref_name }}-linux-arm64.tar.gz dist/mp3rgain-${{ github.ref_name }}-linux-arm64.tar.gz.sha256 dist/mp3rgain-${{ github.ref_name }}-windows-x86_64.zip dist/mp3rgain-${{ github.ref_name }}-windows-x86_64.zip.sha256 dist/mp3rgain-${{ github.ref_name }}-windows-arm64.zip dist/mp3rgain-${{ github.ref_name }}-windows-arm64.zip.sha256 dist/mp3rgui-${{ github.ref_name }}-macos-universal.dmg dist/mp3rgui-${{ github.ref_name }}-macos-universal.dmg.sha256 dist/mp3rgui-${{ github.ref_name }}-macos-universal.tar.gz dist/mp3rgui-${{ github.ref_name }}-macos-universal.tar.gz.sha256 dist/mp3rgui-${{ github.ref_name }}-linux-x86_64.tar.gz dist/mp3rgui-${{ github.ref_name }}-linux-arm64.tar.gz dist/mp3rgui-${{ github.ref_name }}-windows-x86_64.zip dist/mp3rgui-${{ github.ref_name }}-windows-x86_64.zip.sha256 dist/mp3rgui-${{ github.ref_name }}-windows-arm64.zip dist/mp3rgui-${{ github.ref_name }}-windows-arm64.zip.sha256 dist/mp3rgui-${{ github.ref_name }}-windows-setup.exe dist/mp3rgui-${{ github.ref_name }}-windows-setup.exe.sha256 dist/mp3rgui-windows-setup.exe dist/mp3rgui-windows-setup.exe.sha256 draft: false generate_release_notes: true # Update Homebrew tap update-homebrew: name: Update Homebrew Tap needs: release runs-on: ubuntu-latest continue-on-error: true steps: - name: Checkout homebrew-tap uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: M-Igashi/homebrew-tap token: ${{ secrets.HOMEBREW_TAP_TOKEN }} path: homebrew-tap - name: Update CLI formula env: TAG: ${{ github.ref_name }} MACOS_SHA256: ${{ needs.release.outputs.macos_sha256 }} VERSION: ${{ needs.release.outputs.version }} run: | cd homebrew-tap/Formula sed -i "s|url \"https://github.com/M-Igashi/mp3rgain/releases/download/v[^\"]*|url \"https://github.com/M-Igashi/mp3rgain/releases/download/${TAG}/mp3rgain-${TAG}-macos-universal.tar.gz|" mp3rgain.rb sed -i "s|sha256 \"[^\"]*\"|sha256 \"${MACOS_SHA256}\"|" mp3rgain.rb sed -i "s|version \"[^\"]*\"|version \"${VERSION}\"|" mp3rgain.rb - name: Update GUI cask env: GUI_MACOS_DMG_SHA256: ${{ needs.release.outputs.gui_macos_dmg_sha256 }} VERSION: ${{ needs.release.outputs.version }} run: | cd homebrew-tap/Casks sed -i "s|version \"[^\"]*\"|version \"${VERSION}\"|" mp3rgui.rb sed -i "s|sha256 \"[^\"]*\"|sha256 \"${GUI_MACOS_DMG_SHA256}\"|" mp3rgui.rb - name: Commit and push env: VERSION: ${{ needs.release.outputs.version }} run: | cd homebrew-tap git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add Formula/mp3rgain.rb Casks/mp3rgui.rb git commit -m "Update mp3rgain and mp3rgui to $VERSION" || exit 0 git push # Build Debian package build-deb: name: Build Debian Package (${{ matrix.arch }}) needs: release runs-on: ${{ matrix.os }} permissions: contents: write continue-on-error: true strategy: matrix: include: - arch: amd64 os: ubuntu-latest - arch: arm64 os: ubuntu-24.04-arm steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential debhelper devscripts fakeroot - name: Install Rust uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable - name: Setup debian directory run: cp -r packages/debian/debian . - name: Update changelog version env: VERSION: ${{ needs.release.outputs.version }} run: | DATE=$(date -R) printf 'mp3rgain (%s-1) unstable; urgency=medium\n\n * Release %s\n\n -- Jesse Pinkman %s\n' \ "$VERSION" "$VERSION" "$DATE" > debian/changelog echo "=== Generated changelog ===" cat debian/changelog echo "===" - name: Build package run: dpkg-buildpackage -us -uc -b -d - name: List built packages run: ls -la ../mp3rgain*.deb - name: Generate checksum env: VERSION: ${{ needs.release.outputs.version }} ARCH: ${{ matrix.arch }} run: | cd .. sha256sum "mp3rgain_${VERSION}-1_${ARCH}.deb" > "mp3rgain_${VERSION}-1_${ARCH}.deb.sha256" - name: Upload to release env: ARCH: ${{ matrix.arch }} uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v2 with: files: | ../mp3rgain_${{ needs.release.outputs.version }}-1_${{ matrix.arch }}.deb ../mp3rgain_${{ needs.release.outputs.version }}-1_${{ matrix.arch }}.deb.sha256 # Build GUI Debian package build-deb-gui: name: Build GUI Debian Package (${{ matrix.arch }}) needs: release runs-on: ${{ matrix.os }} permissions: contents: write continue-on-error: true strategy: matrix: include: - arch: amd64 os: ubuntu-latest - arch: arm64 os: ubuntu-24.04-arm steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential debhelper devscripts fakeroot libxkbcommon-dev libwayland-dev libgtk-3-dev - name: Install Rust uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable - name: Setup debian directory run: cp -r packages/debian-gui/debian . - name: Update changelog version env: VERSION: ${{ needs.release.outputs.version }} run: | DATE=$(date -R) printf 'mp3rgui (%s-1) unstable; urgency=medium\n\n * Release %s\n\n -- Jesse Pinkman %s\n' \ "$VERSION" "$VERSION" "$DATE" > debian/changelog echo "=== Generated changelog ===" cat debian/changelog echo "===" - name: Build package run: dpkg-buildpackage -us -uc -b -d - name: List built packages run: ls -la ../mp3rgui*.deb - name: Generate checksum env: VERSION: ${{ needs.release.outputs.version }} ARCH: ${{ matrix.arch }} run: | cd .. sha256sum "mp3rgui_${VERSION}-1_${ARCH}.deb" > "mp3rgui_${VERSION}-1_${ARCH}.deb.sha256" - name: Upload to release env: ARCH: ${{ matrix.arch }} uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v2 with: files: | ../mp3rgui_${{ needs.release.outputs.version }}-1_${{ matrix.arch }}.deb ../mp3rgui_${{ needs.release.outputs.version }}-1_${{ matrix.arch }}.deb.sha256 # Publish to crates.io publish-cargo: name: Publish to crates.io needs: release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install Rust uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable - name: Publish to crates.io env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish --token "$CARGO_REGISTRY_TOKEN" # Update AUR package (mp3rgui) update-aur: name: Update AUR Package needs: release runs-on: ubuntu-latest permissions: contents: write continue-on-error: true steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master - name: Setup SSH for AUR env: AUR_SSH_KEY: ${{ secrets.AUR_SSH_KEY }} run: | mkdir -p ~/.ssh echo "$AUR_SSH_KEY" > ~/.ssh/aur chmod 600 ~/.ssh/aur ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null printf 'Host aur.archlinux.org\n User aur\n IdentityFile ~/.ssh/aur\n IdentitiesOnly yes\n' >> ~/.ssh/config - name: Update GUI PKGBUILD version env: VERSION: ${{ needs.release.outputs.version }} run: | sed -i "s/^pkgver=.*/pkgver=${VERSION}/" packages/aur-gui/PKGBUILD sed -i "s/^pkgrel=.*/pkgrel=1/" packages/aur-gui/PKGBUILD sed -i "s/pkgver = .*/pkgver = ${VERSION}/" packages/aur-gui/.SRCINFO sed -i "s/pkgrel = .*/pkgrel = 1/" packages/aur-gui/.SRCINFO sed -i "s|source = https://github.com/M-Igashi/mp3rgain/archive/v.*.tar.gz|source = https://github.com/M-Igashi/mp3rgain/archive/v${VERSION}.tar.gz|" packages/aur-gui/.SRCINFO - name: Commit and push to GitHub env: VERSION: ${{ needs.release.outputs.version }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add packages/aur-gui/ git commit -m "Update AUR mp3rgui to $VERSION" || exit 0 git push - name: Push to AUR (mp3rgui) env: VERSION: ${{ needs.release.outputs.version }} run: | git clone ssh://aur@aur.archlinux.org/mp3rgui.git /tmp/aur-mp3rgui cp packages/aur-gui/PKGBUILD /tmp/aur-mp3rgui/ cp packages/aur-gui/.SRCINFO /tmp/aur-mp3rgui/ cp packages/aur-gui/mp3rgui.desktop /tmp/aur-mp3rgui/ cd /tmp/aur-mp3rgui git config user.name "M-Igashi" git config user.email "M-Igashi@users.noreply.github.com" git add PKGBUILD .SRCINFO mp3rgui.desktop git commit -m "Update to version ${VERSION}" || exit 0 git push