evtx 0.12.1

A Fast (and safe) parser for the Windows XML Event Log (EVTX) format
Documentation
name: release

on:
  push:
    # Enable when testing release infrastructure on a branch.
    # branches:
    # - gh-actions
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
  workflow_dispatch:
    inputs:
      version:
        description: "Release tag (e.g. v0.12.0). Leave empty to use v<version> from Cargo.toml"
        required: false
        default: ""
      dry_run:
        description: "Build all matrix legs but skip release creation and asset upload"
        type: boolean
        required: false
        default: false

permissions:
  contents: write

jobs:
  create-release:
    name: create-release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Resolve release version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "push" ]; then
            VERSION="$GITHUB_REF_NAME"
          elif [ -n "${{ inputs.version }}" ]; then
            VERSION="${{ inputs.version }}"
          else
            VERSION="v$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)"
          fi
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
          echo "version is: $VERSION"

      - name: Create GitHub release (idempotent)
        if: ${{ inputs.dry_run != true }}
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{ steps.version.outputs.version }}
        run: |
          gh release view "$VERSION" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1 \
            || gh release create "$VERSION" --repo "$GITHUB_REPOSITORY" --title "$VERSION" --notes ""

  build-release:
    name: build-release
    needs: ["create-release"]
    runs-on: ${{ matrix.os }}
    env:
      TARGET_DIR: ./target
      RUST_BACKTRACE: 1
      MACOSX_DEPLOYMENT_TARGET: 10.12
      RELEASE_VERSION: ${{ needs.create-release.outputs.version }}

    strategy:
      matrix:
        build:
          [
            linux,
            linux-aarch64,
            linux-static,
            macos-aarch64,
            macos-x86,
            windows,
          ]
        include:
          - build: linux
            os: ubuntu-22.04
            target: x86_64-unknown-linux-gnu
          - build: linux-aarch64
            os: ubuntu-22.04
            target: aarch64-unknown-linux-gnu
          - build: linux-static
            os: ubuntu-22.04
            target: x86_64-unknown-linux-musl
          - build: macos-aarch64
            os: macos-14
            target: aarch64-apple-darwin
          - build: macos-x86
            os: macos-15
            target: x86_64-apple-darwin
          - build: windows
            os: windows-2022
            target: x86_64-pc-windows-msvc

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Install Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: 1.92.0
          targets: ${{ matrix.target }}
          components: llvm-tools

      - name: Setup Rust environment (non-Windows)
        if: runner.os != 'Windows'
        shell: bash
        run: |
          echo "RUSTUP_HOME=$HOME/.rustup" >> $GITHUB_ENV
          echo "CARGO_HOME=$HOME/.cargo" >> $GITHUB_ENV
          LLVM_TOOLS_PATH=$(rustc --print sysroot)/lib/rustlib/${{ matrix.target }}/bin
          echo "PATH=$LLVM_TOOLS_PATH:$HOME/.cargo/bin:$PATH" >> $GITHUB_ENV

      - name: Set up Homebrew (macOS only)
        if: runner.os == 'macOS'
        id: set-up-homebrew
        uses: Homebrew/actions/setup-homebrew@master

      - name: Install LLVM 19 (macOS only)
        if: runner.os == 'macOS'
        run: |
          brew install llvm@19
          echo "$(brew --prefix llvm@19)/bin" >> $GITHUB_PATH

      - name: Install Cross toolchain (zig)
        if: matrix.build == 'macos-aarch64' || matrix.build == 'linux-aarch64'
        uses: mlugg/setup-zig@v2
        with:
          version: 0.11.0
          use-cache: false

      - name: Build PGO Binary (Linux)
        if: matrix.build == 'linux'
        shell: bash
        run: |
          export TARGET=${{ matrix.target }}
          ./build_pgo.sh
        env:
          HOME: ${{ github.workspace }}

      - name: Build release binary (macOS)
        if: matrix.build == 'macos-x86' || matrix.build == 'macos-aarch64'
        run: |
          export TARGET=${{ matrix.target }}
          ./build_pgo.sh
        env:
          HOME: ${{ github.workspace }}

      - name: Build release binary (linux MUSL)
        if: matrix.build == 'linux-static'
        run: cargo build --target ${{ matrix.target }} --release --features wevt_templates

      - name: Build release binary (Windows)
        if: matrix.build == 'windows'
        run: cargo build --target ${{ matrix.target }} --release --features fast-alloc,wevt_templates

      - name: Build release binary (Linux AARCH64)
        if: matrix.build == 'linux-aarch64'
        run: |
          cargo install cargo-zigbuild
          cargo zigbuild --target ${{ matrix.target }} --release --features fast-alloc,wevt_templates

      - name: Build archive
        shell: bash
        run: |
          if [ "${{ matrix.build }}" = "windows" ]; then
            echo "ASSET=target/${{ matrix.target }}/release/evtx_dump.exe" >> $GITHUB_ENV
            echo "ASSET_NAME=evtx_dump-${{ env.RELEASE_VERSION }}.exe" >> $GITHUB_ENV
          else
            echo "ASSET=target/${{ matrix.target }}/release/evtx_dump" >> $GITHUB_ENV
            echo "ASSET_NAME=evtx_dump-${{ env.RELEASE_VERSION }}-${{ matrix.target }}" >> $GITHUB_ENV
          fi
      - name: Upload release archive
        if: ${{ inputs.dry_run != true }}
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          upload_path="$ASSET"
          if [ "$(basename "$ASSET")" != "$ASSET_NAME" ]; then
            upload_path="target/$ASSET_NAME"
            cp "$ASSET" "$upload_path"
          fi
          gh release upload "$RELEASE_VERSION" "$upload_path" --clobber