mdtablefix 0.6.1

`mdtablefix` unb0rks and reflows Markdown tables so that each column has a uniform width. When the `--wrap` option is used, it also wraps paragraphs and list items to 80 columns.
Documentation
name: Release Binary

on:
  push:
    tags:
      - 'v*.*.*'
  workflow_dispatch:
    inputs:
      release_tag:
        description: Existing release tag to build and backfill
        required: true
        type: string

env:
  REPO_NAME: ${{ github.event.repository.name }}
  RELEASE_TAG: ${{ inputs.release_tag || github.ref_name }}
  RELEASE_RUST_VERSION: 1.89.0
  CROSS_VERSION: 0.2.5
  CROSS_LINUX_X64_SHA256: 642375d1bcf3bd88272c32ba90e999f3d983050adf45e66bd2d3887e8e838bad

permissions:
  contents: read

concurrency:
  group: release-${{ github.repository }}-${{ inputs.release_tag || github.ref_name }}
  cancel-in-progress: false

jobs:
  prepare-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
        with:
          ref: ${{ env.RELEASE_TAG }}
      - name: Verify release tag matches Cargo.toml
        run: |
          set -euo pipefail
          tag="${RELEASE_TAG#v}"
          cargo_version="$(python3 -c \
            'import pathlib, tomllib; print(tomllib.loads(pathlib.Path("Cargo.toml").read_text(encoding="utf-8"))["package"]["version"])')"
          if [[ "${tag}" != "${cargo_version}" ]]; then
            echo "release tag ${tag} does not match Cargo.toml version ${cargo_version}" >&2
            exit 1
          fi
      - name: Create the GitHub release when absent
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          if ! gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
            gh release create "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" \
              --generate-notes --verify-tag
          fi

  build:
    needs: prepare-release
    runs-on: ${{ matrix.runner }}
    permissions:
      contents: write
    defaults:
      run:
        # Windows runners default to PowerShell; every step here is written for
        # bash, and Git Bash is present on all three runner images.
        shell: bash
    strategy:
      fail-fast: false
      matrix:
        include:
          # Every row publishes a cargo-binstall archive; the contract test
          # in tests/release_packaging.rs asserts that this set and the set of
          # targets the binstall metadata promises are the same.
          # `cross` covers the targets that need a foreign libc; the native
          # runners build their own platform directly, because `cross` cannot
          # produce Apple or MSVC binaries from Linux.
          - os: linux
            arch: x86_64
            target: x86_64-unknown-linux-gnu
            runner: ubuntu-latest
            builder: cross
          - os: linux
            arch: aarch64
            target: aarch64-unknown-linux-gnu
            runner: ubuntu-latest
            builder: cross
          - os: macos
            arch: x86_64
            target: x86_64-apple-darwin
            runner: macos-15
            builder: cargo
          - os: macos
            arch: aarch64
            target: aarch64-apple-darwin
            runner: macos-15
            builder: cargo
          - os: windows
            arch: x86_64
            target: x86_64-pc-windows-msvc
            runner: windows-latest
            builder: cargo
          - os: freebsd
            arch: x86_64
            target: x86_64-unknown-freebsd
            runner: ubuntu-latest
            builder: cross
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
        with:
          ref: ${{ env.RELEASE_TAG }}
      - name: Set reproducible release timestamp
        run: echo "SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)" >> "${GITHUB_ENV}"
      - name: Setup Rust
        uses: leynos/shared-actions/.github/actions/setup-rust@6dea5677a84fec60ca51b07202570e3af12ffdb4
        with:
          toolchain: ${{ env.RELEASE_RUST_VERSION }}
          install-binstall: false
          use-sccache: false
      - name: Cache the official cross binaries
        if: matrix.builder == 'cross'
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
        with:
          path: ~/.local/share/mdtablefix-tools/cross-v${{ env.CROSS_VERSION }}
          key: cross-official-v${{ env.CROSS_VERSION }}-${{ runner.os }}-${{ runner.arch }}
      - name: Install cross from its official release
        if: matrix.builder == 'cross'
        run: |
          set -euo pipefail
          cross_dir="${HOME}/.local/share/mdtablefix-tools/cross-v${CROSS_VERSION}"
          cross_binary="${cross_dir}/cross"
          expected_version="cross ${CROSS_VERSION}"
          probe_cross_version() {
            (
              cd "${RUNNER_TEMP}"
              "${cross_binary}" --version 2>/dev/null
            ) | sed -n '1p'
          }
          installed_version=""
          if [[ -x "${cross_binary}" ]]; then
            if ! installed_version="$(probe_cross_version)"; then
              installed_version=""
            fi
          fi
          if [[ "${installed_version}" != "${expected_version}" ]]; then
            archive="${RUNNER_TEMP}/cross.tar.gz"
            url="https://github.com/cross-rs/cross/releases/download/v${CROSS_VERSION}/cross-x86_64-unknown-linux-gnu.tar.gz"
            curl --fail --location --proto '=https' --tlsv1.2 "${url}" -o "${archive}"
            echo "${CROSS_LINUX_X64_SHA256}  ${archive}" | sha256sum --check --status
            mkdir -p "${cross_dir}"
            rm -f "${cross_dir}/cross" "${cross_dir}/cross-util"
            tar --extract --gzip --file "${archive}" --directory "${cross_dir}" \
              cross cross-util
            chmod 0755 "${cross_dir}/cross" "${cross_dir}/cross-util"
          fi
          installed_version="$(probe_cross_version)"
          [[ "${installed_version}" == "${expected_version}" ]]
          echo "${cross_dir}" >> "${GITHUB_PATH}"
      - name: Cache cargo registry
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-${{ matrix.target }}-rust-${{ env.RELEASE_RUST_VERSION }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-rust-${{ env.RELEASE_RUST_VERSION }}-cargo-
      - name: Add release target
        run: rustup target add --toolchain "${RELEASE_RUST_VERSION}" ${{ matrix.target }}
      - name: Build release binary
        run: |
          set -euo pipefail
          if [[ "${{ matrix.builder }}" == "cross" ]]; then
            cross +"${RELEASE_RUST_VERSION}" build --release --target ${{ matrix.target }}
          else
            cargo +"${RELEASE_RUST_VERSION}" build --release --target ${{ matrix.target }}
          fi
      - name: Prepare artifact
        run: |
          set -euo pipefail
          binary_ext=""
          if [[ "${{ matrix.target }}" == *windows* ]]; then
            binary_ext=".exe"
          fi
          # The Windows image exposes the interpreter as `python`; the Linux and
          # macOS images expose `python3`.
          python_bin=python3
          command -v python3 >/dev/null 2>&1 || python_bin=python
          "${python_bin}" scripts/package_release_artifacts.py \
            --binary "target/${{ matrix.target }}/release/${REPO_NAME}${binary_ext}" \
            --artifact-dir "artifacts/${{ matrix.os }}-${{ matrix.arch }}" \
            --package-name "${REPO_NAME}" \
            --version "${RELEASE_TAG#v}" \
            --target "${{ matrix.target }}" \
            --os "${{ matrix.os }}" \
            --arch "${{ matrix.arch }}"
      - name: Upload release artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
        with:
          name: ${{ env.REPO_NAME }}-${{ matrix.os }}-${{ matrix.arch }}
          path: artifacts/${{ matrix.os }}-${{ matrix.arch }}
          overwrite: true
      - name: Publish this target's release assets
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -euo pipefail
          artifact_dir="artifacts/${{ matrix.os }}-${{ matrix.arch }}"
          existing_dir="${RUNNER_TEMP}/existing-release-assets/${{ matrix.target }}"
          mkdir -p "${existing_dir}"

          for file in "${artifact_dir}"/*; do
            asset_name="$(basename "${file}")"
            asset_id="$(gh api \
              "repos/${GITHUB_REPOSITORY}/releases/tags/${RELEASE_TAG}" \
              --jq ".assets[] | select(.name == \"${asset_name}\") | .id")"
            if [[ -n "${asset_id}" ]]; then
              existing_file="${existing_dir}/${asset_name}"
              gh api --method GET -H "Accept: application/octet-stream" \
                "repos/${GITHUB_REPOSITORY}/releases/assets/${asset_id}" \
                > "${existing_file}"
              if ! cmp --silent "${file}" "${existing_file}"; then
                echo "release asset ${asset_name} exists with different content" >&2
                exit 1
              fi
              echo "release asset ${asset_name} already exists with identical content"
              continue
            fi
            gh release upload "${RELEASE_TAG}" "${file}" \
              --repo "${GITHUB_REPOSITORY}"
          done