name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
publish_crate:
description: "Publish to crates.io"
type: boolean
default: true
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
jobs:
build-linux:
name: Build Linux (${{ matrix.target }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- x86_64-unknown-linux-musl
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
key: linux-${{ matrix.target }}
- name: Install cross
run: cargo install cross --locked
- name: Build binary
run: cross build --release --target ${{ matrix.target }} --package markdown-tui-explorer
- name: Strip binary
run: |
TARGET_STRIP=""
case "${{ matrix.target }}" in
aarch64-unknown-linux-gnu)
TARGET_STRIP="aarch64-linux-gnu-strip"
sudo apt-get install -y binutils-aarch64-linux-gnu
;;
*)
TARGET_STRIP="strip"
;;
esac
$TARGET_STRIP target/${{ matrix.target }}/release/markdown-reader
- name: Package tarball
run: |
VERSION=${GITHUB_REF_NAME#v}
TARBALL="markdown-reader-${VERSION}-${{ matrix.target }}.tar.gz"
tar -czf "$TARBALL" -C target/${{ matrix.target }}/release markdown-reader
echo "TARBALL=$TARBALL" >> "$GITHUB_ENV"
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: markdown-reader-${{ matrix.target }}
path: ${{ env.TARBALL }}
retention-days: 1
build-macos:
name: Build macOS (${{ matrix.target }})
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
target:
- x86_64-apple-darwin
- aarch64-apple-darwin
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: macos-${{ matrix.target }}
- name: Build binary
run: cargo build --release --target ${{ matrix.target }} --package markdown-tui-explorer
- name: Strip binary
run: strip target/${{ matrix.target }}/release/markdown-reader
- name: Package tarball
run: |
VERSION=${GITHUB_REF_NAME#v}
TARBALL="markdown-reader-${VERSION}-${{ matrix.target }}.tar.gz"
tar -czf "$TARBALL" -C target/${{ matrix.target }}/release markdown-reader
echo "TARBALL=$TARBALL" >> "$GITHUB_ENV"
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: markdown-reader-${{ matrix.target }}
path: ${{ env.TARBALL }}
retention-days: 1
release:
name: Create GitHub Release
needs: [build-linux, build-macos]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
merge-multiple: true
- name: Generate SHA-256 checksums
working-directory: artifacts
run: sha256sum *.tar.gz > SHA256SUMS
- name: Extract changelog section
id: changelog
run: |
VERSION=${GITHUB_REF_NAME#v}
if [ -f CHANGELOG.md ]; then
# Extract the block between ## [version] and the next ## [
BODY=$(awk "/^## \[${VERSION}\]/{found=1; next} found && /^## \[/{exit} found{print}" CHANGELOG.md)
else
BODY="Release ${GITHUB_REF_NAME}"
fi
printf '%s' "$BODY" > release_notes.md
- name: Publish GitHub Release
uses: softprops/action-gh-release@v3
with:
body_path: release_notes.md
files: |
artifacts/*.tar.gz
artifacts/SHA256SUMS
token: ${{ secrets.GITHUB_TOKEN }}
publish-crate:
name: Publish parent crate to crates.io
needs: [release]
runs-on: ubuntu-latest
if: >
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) ||
(github.event_name == 'workflow_dispatch' && inputs.publish_crate == true)
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Publish parent crate
run: cargo publish --package markdown-tui-explorer --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
publish-homebrew:
name: Update Homebrew tap
needs: [release]
runs-on: ubuntu-latest
env:
HAS_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN != '' && 'true' || 'false' }}
steps:
- name: Report skip reason
if: env.HAS_TOKEN != 'true'
run: echo "HOMEBREW_TAP_TOKEN is not set on this repo — skipping Homebrew formula publish."
- name: Checkout source repo
if: env.HAS_TOKEN == 'true'
uses: actions/checkout@v6
- name: Download release checksums
if: env.HAS_TOKEN == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p artifacts
gh release download "$GITHUB_REF_NAME" \
-R "$GITHUB_REPOSITORY" \
-p SHA256SUMS \
-D artifacts
- name: Checkout tap repo
if: env.HAS_TOKEN == 'true'
uses: actions/checkout@v6
with:
repository: leboiko/homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-tap
- name: Render formula
if: env.HAS_TOKEN == 'true'
run: |
VERSION=${GITHUB_REF_NAME#v}
mkdir -p homebrew-tap/Formula
./scripts/render-homebrew-formula.sh "$VERSION" artifacts/SHA256SUMS \
> homebrew-tap/Formula/markdown-reader.rb
- name: Commit and push
if: env.HAS_TOKEN == 'true'
working-directory: homebrew-tap
run: |
VERSION=${GITHUB_REF_NAME#v}
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "Formula already up to date for v${VERSION}"
exit 0
fi
git add Formula/markdown-reader.rb
git commit -m "markdown-reader ${VERSION}"
git push