name: Release
on:
push:
tags:
- "v*"
permissions:
contents: write
jobs:
build-macos:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup Rust
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 with:
toolchain: stable
- name: Add targets
run: |
rustup target add aarch64-apple-darwin
rustup target add x86_64-apple-darwin
- name: Build arm64
run: cargo build --release --target aarch64-apple-darwin
- name: Build x86_64
run: cargo build --release --target x86_64-apple-darwin
- name: Create universal binary
run: |
mkdir -p release
lipo -create \
target/aarch64-apple-darwin/release/headroom \
target/x86_64-apple-darwin/release/headroom \
-output release/headroom
- name: Get version
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create tarball
run: |
cd release
tar -czvf headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz headroom
- name: Calculate SHA256
id: sha256
run: |
SHA256=$(shasum -a 256 release/headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz | awk '{print $1}')
echo "SHA256=$SHA256" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: macos-universal
path: release/headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz
- name: Save SHA256
run: echo "${{ steps.sha256.outputs.SHA256 }}" > sha256-macos-universal.txt
- name: Upload SHA256
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: sha256-macos-universal
path: sha256-macos-universal.txt
build-linux-x86_64:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup Rust
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 with:
toolchain: stable
- name: Build
run: cargo build --release
- name: Get version
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create tarball
run: |
mkdir -p release
cp target/release/headroom release/
cd release
tar -czvf headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz headroom
- name: Calculate SHA256
id: sha256
run: |
SHA256=$(sha256sum release/headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz | awk '{print $1}')
echo "SHA256=$SHA256" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: linux-x86_64
path: release/headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz
- name: Save SHA256
run: echo "${{ steps.sha256.outputs.SHA256 }}" > sha256-linux-x86_64.txt
- name: Upload SHA256
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: sha256-linux-x86_64
path: sha256-linux-x86_64.txt
build-linux-aarch64:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup Rust
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 with:
toolchain: stable
- name: Install cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Build with cross
run: cross build --release --target aarch64-unknown-linux-gnu
- name: Get version
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create tarball
run: |
mkdir -p release
cp target/aarch64-unknown-linux-gnu/release/headroom release/
cd release
tar -czvf headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz headroom
- name: Calculate SHA256
id: sha256
run: |
SHA256=$(sha256sum release/headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz | awk '{print $1}')
echo "SHA256=$SHA256" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: linux-aarch64
path: release/headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz
- name: Save SHA256
run: echo "${{ steps.sha256.outputs.SHA256 }}" > sha256-linux-aarch64.txt
- name: Upload SHA256
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: sha256-linux-aarch64
path: sha256-linux-aarch64.txt
build-windows:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup Rust
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 with:
toolchain: stable
- name: Build
run: cargo build --release
- name: Get version
id: version
shell: bash
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create zip
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path release
Copy-Item target\release\headroom.exe release\
Compress-Archive -Path release\headroom.exe -DestinationPath release\headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip
- name: Calculate SHA256
id: sha256
shell: pwsh
run: |
$hash = (Get-FileHash release\headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip -Algorithm SHA256).Hash.ToLower()
echo "SHA256=$hash" >> $env:GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: windows-x86_64
path: release/headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip
- name: Save SHA256
shell: bash
run: echo "${{ steps.sha256.outputs.SHA256 }}" > sha256-windows-x86_64.txt
- name: Upload SHA256
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: sha256-windows-x86_64
path: sha256-windows-x86_64.txt
release:
needs: [build-macos, build-linux-x86_64, build-linux-aarch64, build-windows]
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.VERSION }}
version_num: ${{ steps.version.outputs.VERSION_NUM }}
macos_sha256: ${{ steps.macos_sha256.outputs.SHA256 }}
windows_sha256: ${{ steps.windows_sha256.outputs.SHA256 }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Get version
id: version
run: |
VERSION="${GITHUB_REF#refs/tags/}"
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "VERSION_NUM=${VERSION#v}" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 with:
path: artifacts
- name: Prepare release files
run: |
mkdir -p release
mv artifacts/macos-universal/*.tar.gz release/
mv artifacts/linux-x86_64/*.tar.gz release/
mv artifacts/linux-aarch64/*.tar.gz release/
mv artifacts/windows-x86_64/*.zip release/
- name: Create checksums file
run: |
cd release
cat ../artifacts/sha256-macos-universal/sha256-macos-universal.txt | while read hash; do echo "$hash headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz"; done > checksums.txt
cat ../artifacts/sha256-linux-x86_64/sha256-linux-x86_64.txt | while read hash; do echo "$hash headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz"; done >> checksums.txt
cat ../artifacts/sha256-linux-aarch64/sha256-linux-aarch64.txt | while read hash; do echo "$hash headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz"; done >> checksums.txt
cat ../artifacts/sha256-windows-x86_64/sha256-windows-x86_64.txt | while read hash; do echo "$hash headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip"; done >> checksums.txt
mv checksums.txt headroom-${{ steps.version.outputs.VERSION }}-checksums.txt
- name: Get macOS SHA256
id: macos_sha256
run: |
SHA256=$(cat artifacts/sha256-macos-universal/sha256-macos-universal.txt)
echo "SHA256=$SHA256" >> $GITHUB_OUTPUT
- name: Get Windows SHA256
id: windows_sha256
run: |
SHA256=$(cat artifacts/sha256-windows-x86_64/sha256-windows-x86_64.txt)
echo "SHA256=$SHA256" >> $GITHUB_OUTPUT
- name: Check for release notes
id: release_notes
run: |
if [ -f "RELEASE_NOTES.md" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Create Release (with custom notes)
if: steps.release_notes.outputs.exists == 'true'
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 with:
files: |
release/headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip
release/headroom-${{ steps.version.outputs.VERSION }}-checksums.txt
body_path: RELEASE_NOTES.md
append_body: true
- name: Create Release (auto-generated notes)
if: steps.release_notes.outputs.exists == 'false'
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 with:
files: |
release/headroom-${{ steps.version.outputs.VERSION }}-macos-universal.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-linux-aarch64.tar.gz
release/headroom-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip
release/headroom-${{ steps.version.outputs.VERSION }}-checksums.txt
generate_release_notes: true
body: |
## Installation
| Platform | Command |
|----------|---------|
| **macOS (Homebrew)** | `brew install M-Igashi/tap/headroom` |
| **Windows (Scoop)** | `scoop bucket add headroom https://github.com/M-Igashi/scoop-bucket && scoop install headroom` |
| **Windows (winget)** | `winget install M-Igashi.headroom` |
| **Cargo** | `cargo install headroom` |
**Dependencies:** ffmpeg and mp3rgain must be installed separately.
## Checksums
See `headroom-${{ steps.version.outputs.VERSION }}-checksums.txt` for SHA256 checksums of all binaries.
## Note
mp3rgain is now built-in as a library dependency. No separate installation required.
publish-cargo:
needs: [release]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup Rust
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 with:
toolchain: stable
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --token $CARGO_REGISTRY_TOKEN
update-homebrew:
needs: [release]
runs-on: ubuntu-latest
steps:
- name: Update Homebrew formula
env:
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
VERSION="${{ needs.release.outputs.version }}"
VERSION_NUM="${{ needs.release.outputs.version_num }}"
SHA256="${{ needs.release.outputs.macos_sha256 }}"
git clone https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/M-Igashi/homebrew-tap.git
cd homebrew-tap
cat > Formula/headroom.rb << 'FORMULA'
class Headroom < Formula
desc "Audio loudness analyzer and gain adjustment tool for mastering and DJ workflows"
homepage "https://github.com/M-Igashi/headroom"
url "https://github.com/M-Igashi/headroom/releases/download/VERSION_PLACEHOLDER/headroom-VERSION_PLACEHOLDER-macos-universal.tar.gz"
sha256 "SHA256_PLACEHOLDER"
version "VERSION_NUM_PLACEHOLDER"
license "MIT"
depends_on "ffmpeg"
def install
bin.install "headroom"
end
def caveats
<<~EOS
mp3rgain is now built-in as a library dependency.
No separate installation required for lossless MP3 gain adjustment.
EOS
end
test do
assert_match "headroom", shell_output("#{bin}/headroom --version")
end
end
FORMULA
sed -i "s|VERSION_PLACEHOLDER|${VERSION}|g" Formula/headroom.rb
sed -i "s|SHA256_PLACEHOLDER|${SHA256}|g" Formula/headroom.rb
sed -i "s|VERSION_NUM_PLACEHOLDER|${VERSION_NUM}|g" Formula/headroom.rb
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/headroom.rb
git commit -m "headroom ${VERSION_NUM}"
git push
update-scoop:
needs: [release]
runs-on: ubuntu-latest
steps:
- name: Update Scoop bucket
env:
SCOOP_BUCKET_TOKEN: ${{ secrets.SCOOP_BUCKET_TOKEN }}
run: |
VERSION="${{ needs.release.outputs.version }}"
VERSION_NUM="${{ needs.release.outputs.version_num }}"
SHA256="${{ needs.release.outputs.windows_sha256 }}"
git clone https://x-access-token:${SCOOP_BUCKET_TOKEN}@github.com/M-Igashi/scoop-bucket.git
cd scoop-bucket
cat > bucket/headroom.json << MANIFEST
{
"version": "${VERSION_NUM}",
"description": "Audio loudness analyzer and gain adjustment tool for mastering and DJ workflows",
"homepage": "https://github.com/M-Igashi/headroom",
"license": "MIT",
"architecture": {
"64bit": {
"url": "https://github.com/M-Igashi/headroom/releases/download/${VERSION}/headroom-${VERSION}-windows-x86_64.zip",
"hash": "${SHA256}",
"bin": "headroom.exe"
}
},
"depends": "ffmpeg",
"notes": "mp3rgain is now built-in as a library dependency. No separate installation required.",
"checkver": {
"github": "https://github.com/M-Igashi/headroom"
},
"autoupdate": {
"architecture": {
"64bit": {
"url": "https://github.com/M-Igashi/headroom/releases/download/v\$version/headroom-v\$version-windows-x86_64.zip"
}
}
}
}
MANIFEST
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add bucket/headroom.json
git commit -m "headroom ${VERSION_NUM}"
git push