Build MediaInfo #13
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 MediaInfo | |
| on: | |
| schedule: | |
| # Runs at 00:00 UTC on Tuesdays, Thursdays, and Saturdays | |
| - cron: '0 0 * * 2,4,6' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| check-version: | |
| name: Safety Measure & Version Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 140 | |
| outputs: | |
| build_needed: ${{ steps.check.outputs.build_needed }} | |
| version: ${{ steps.check.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Check Upstream Version vs Latest Release | |
| id: check | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| echo "Fetching Latest MediaInfo Source..." | |
| MI_URL=$(curl -fsSL "https://mediaarea.net/download/binary/mediainfo/" | grep -oP '(?<=href=")\d+(?:\.\d+)+(?=/")' | sort -Vu | tail -n 1) | |
| test -n "$MI_URL" || { echo "❌ FATAL ERROR: Failed to detect latest MediaInfo version."; exit 1; } | |
| echo "💡 Latest MediaInfo version detected: $MI_URL" | |
| # Fetch latest release tag from this repo (suppress error if no releases exist yet) | |
| LATEST_RELEASE=$(gh release view --json tagName -q .tagName 2>/dev/null || echo "none") | |
| echo "💡 Current repository latest release: $LATEST_RELEASE" | |
| if [ "v$MI_URL" == "$LATEST_RELEASE" ]; then | |
| echo "✅ Version v$MI_URL is already built. Exiting workflow early with success." | |
| echo "build_needed=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "🚀 New version detected! Proceeding to build v$MI_URL." | |
| echo "build_needed=true" >> $GITHUB_OUTPUT | |
| echo "version=$MI_URL" >> $GITHUB_OUTPUT | |
| fi | |
| build-binaries: | |
| # Uses the visual_arch for human readability (x64 and ARM64) | |
| name: Compile Binaries (${{ matrix.visual_arch }}) | |
| needs: check-version | |
| if: needs.check-version.outputs.build_needed == 'true' | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 240 # 4-hour safety net for heavy compilation | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| visual_arch: x64 | |
| runner: ubuntu-latest | |
| ext_name: linux64 | |
| - arch: arm64 | |
| visual_arch: ARM64 | |
| runner: ubuntu-24.04-arm | |
| ext_name: linuxarm64 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Build, Extract, and Compress Binary | |
| run: | | |
| set -euo pipefail | |
| mkdir -p ./output ./artifacts | |
| docker buildx build \ | |
| --platform linux/${{ matrix.arch }} \ | |
| --build-arg MI_VERSION=${{ needs.check-version.outputs.version }} \ | |
| --output type=local,dest=./output \ | |
| --cache-to type=gha,mode=max,scope=mediainfo-${{ matrix.arch }} \ | |
| --cache-from type=gha,scope=mediainfo-${{ matrix.arch }} \ | |
| -f Dockerfile . | |
| # Navigate to output, make executable, and compress into a real tar.xz archive | |
| cd ./output | |
| chmod +x mediainfo | |
| TAR_FILENAME="mediainfo-master-latest-${{ matrix.ext_name }}-gpl.tar.xz" | |
| tar -cJf "../artifacts/$TAR_FILENAME" mediainfo | |
| cd .. | |
| - name: Upload Artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: mediainfo-${{ matrix.arch }} | |
| path: ./artifacts/mediainfo-master-latest-${{ matrix.ext_name }}-gpl.tar.xz | |
| retention-days: 1 | |
| release-and-cleanup: | |
| name: Publish Release & Purge Old | |
| needs: [check-version, build-binaries] | |
| if: needs.check-version.outputs.build_needed == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 72 # Safety net for GitHub API uploads | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 2 # Required to fetch the previous commit hash | |
| - name: Download Artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: ./artifacts | |
| merge-multiple: true | |
| - name: Generate Checksums | |
| run: | | |
| set -euo pipefail | |
| cd ./artifacts | |
| echo "Generating SHA256 checksums..." | |
| sha256sum * > checksums.sha256 | |
| cat checksums.sha256 | |
| - name: Strip 'Latest' Tag From Previous Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| OLD_RELEASE_TAG=$(gh release view --json tagName -q .tagName 2>/dev/null || echo "none") | |
| if [ "$OLD_RELEASE_TAG" != "none" ]; then | |
| OLD_TITLE=$(gh release view "$OLD_RELEASE_TAG" --json name -q .name) | |
| # Instantly remove the " - Latest" string from the old title | |
| NEW_OLD_TITLE=$(echo "$OLD_TITLE" | sed 's/ - Latest//g') | |
| echo "Renaming old release '$OLD_TITLE' to '$NEW_OLD_TITLE'" | |
| gh release edit "$OLD_RELEASE_TAG" --title "$NEW_OLD_TITLE" || true | |
| fi | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VERSION: ${{ needs.check-version.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| TAG_NAME="v$VERSION" | |
| # Generate dynamic text variables | |
| DATE_STR=$(date -u +'%d/%m/%Y At %H:%M') | |
| COMMIT_MSG=$(git log -1 --pretty=%B | head -n 1) | |
| PREV_HASH=$(git log -2 --pretty=%H | tail -n 1) | |
| # Create the exact release body you requested | |
| cat <<EOF > release_notes.txt | |
| This Latest Stable Automated Build Of MediaInfo Created On $DATE_STR | |
| $COMMIT_MSG | |
| This reverts commit $PREV_HASH. | |
| EOF | |
| echo "Creating release for $TAG_NAME..." | |
| gh release create "$TAG_NAME" ./artifacts/* \ | |
| --title "MediaInfo $VERSION (Executable) - Latest" \ | |
| --notes-file release_notes.txt | |
| - name: Cleanup Old Releases (Keep Last 4) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| echo "Fetching all releases..." | |
| # Get all releases sorted by creation date (newest first) | |
| RELEASES=$(gh release list --limit 100 | awk '{print $1}') | |
| COUNT=0 | |
| for REL in $RELEASES; do | |
| COUNT=$((COUNT+1)) | |
| if [ $COUNT -gt 4 ]; then | |
| echo "🗑️ Deleting old release: $REL" | |
| gh release delete "$REL" --cleanup-tag -y | |
| else | |
| echo "✅ Keeping release: $REL" | |
| fi | |
| done | |
| keepalive: | |
| name: Repository Keepalive | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'schedule' | |
| timeout-minutes: 61 # Safety net for git push | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Push Keepalive Commit | |
| run: | | |
| set -euo pipefail | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| git checkout -B dev | |
| git commit --allow-empty -m "chore: keepalive to prevent GitHub Actions cron pause [skip ci]" | |
| git push origin dev --force |