ime 1.3.0

A fast, lightweight CLI for reading, writing, and wiping metadata from image files.
name: Release

on:
  push:
    tags:
      - "v*" # Trigger on version tags, e.g., v1.0.0, v0.1.0
  workflow_dispatch:
    inputs:
      version:
        description: 'Version tag for manual release (e.g., v0.1.0-test)'
        required: true
        type: string
      publish_to_crates_io:
        description: 'Also publish to crates.io (leave unchecked for test/manual releases)'
        required: false
        type: boolean
        default: false

permissions:
  contents: write

jobs:
  build-linux:
    name: Build Linux (x86_64-musl)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-musl

      - name: Cache cargo registry and build artifacts
        uses: Swatinem/rust-cache@v2
        with:
          key: x86_64-unknown-linux-musl

      - name: Install mold linker
        uses: rui314/setup-mold@v1

      - name: Install musl-tools
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Build binary
        run: cargo build --release --target x86_64-unknown-linux-musl

      - name: Rename binary for upload
        run: mv target/x86_64-unknown-linux-musl/release/ime target/x86_64-unknown-linux-musl/release/ime-linux-amd64

      - name: Upload binary artifact
        uses: actions/upload-artifact@v4
        with:
          name: ime-linux-amd64
          path: target/x86_64-unknown-linux-musl/release/ime-linux-amd64

  build-windows:
    name: Build Windows (x86_64-msvc)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-pc-windows-msvc

      - name: Cache cargo registry and build artifacts
        uses: Swatinem/rust-cache@v2
        with:
          key: x86_64-pc-windows-msvc

      - name: Cache cargo-xwin binary
        id: cargo-xwin-cache
        uses: actions/cache@v6
        with:
          path: ~/.cargo/bin/cargo-xwin
          key: cargo-xwin-bin-v1

      - name: Install cargo-xwin
        if: steps.cargo-xwin-cache.outputs.cache-hit != 'true'
        run: cargo install --locked cargo-xwin

      - name: Cache Windows SDK/CRT (xwin)
        uses: actions/cache@v6
        with:
          path: /home/runner/.xwin-cache
          key: xwin-sdk-v1

      - name: Build binary
        env:
          XWIN_CACHE_DIR: /home/runner/.xwin-cache
        run: cargo xwin build --release --target x86_64-pc-windows-msvc

      - name: Rename binary for upload
        run: mv target/x86_64-pc-windows-msvc/release/ime.exe target/x86_64-pc-windows-msvc/release/ime-windows-amd64.exe

      - name: Upload binary artifact
        uses: actions/upload-artifact@v4
        with:
          name: ime-windows-amd64.exe
          path: target/x86_64-pc-windows-msvc/release/ime-windows-amd64.exe

  create-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: [build-linux, build-windows]
    steps:
      - name: Download Linux binary
        uses: actions/download-artifact@v4
        with:
          name: ime-linux-amd64
          path: dist/

      - name: Download Windows binary
        uses: actions/download-artifact@v4
        with:
          name: ime-windows-amd64.exe
          path: dist/

      - name: Create Release and Upload Assets
        uses: softprops/action-gh-release@v3
        with:
          tag_name: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || github.ref_name }}
          files: |
            dist/ime-linux-amd64
            dist/ime-windows-amd64.exe
          generate_release_notes: true

  publish-crate:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    needs: [build-linux, build-windows]
    if: github.event_name != 'workflow_dispatch' || github.event.inputs.publish_to_crates_io == 'true'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo registry and build artifacts
        uses: Swatinem/rust-cache@v2
        with:
          key: x86_64-unknown-linux-musl
          save-if: false

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish

  publish-npm:
    name: Publish to NPM
    runs-on: ubuntu-latest
    needs: [build-linux, build-windows]
    if: github.event_name != 'workflow_dispatch'
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'

      - name: Download Linux binary
        uses: actions/download-artifact@v4
        with:
          name: ime-linux-amd64
          path: npm/ime-linux-x64/

      - name: Download Windows binary
        uses: actions/download-artifact@v4
        with:
          name: ime-windows-amd64.exe
          path: npm/ime-win32-x64/

      - name: Prepare binaries and versions
        run: |
          mv npm/ime-linux-x64/ime-linux-amd64 npm/ime-linux-x64/ime
          chmod +x npm/ime-linux-x64/ime
          mv npm/ime-win32-x64/ime-windows-amd64.exe npm/ime-win32-x64/ime.exe

          VERSION=${GITHUB_REF_NAME#v}
          for pkg in npm/*/package.json; do
            tmp=$(mktemp)
            jq ".version = \"$VERSION\"" "$pkg" > "$tmp" && mv "$tmp" "$pkg"
          done

      - name: Publish Linux Package
        run: npm publish --provenance --access public
        working-directory: npm/ime-linux-x64
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Publish Windows Package
        run: npm publish --provenance --access public
        working-directory: npm/ime-win32-x64
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Publish Main Package
        run: npm publish --provenance --access public
        working-directory: npm/ime-cli
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}