wim-parser 0.1.2

A Rust library for parsing Windows Imaging (WIM) files
Documentation
name: Release and Publish

on:
  push:
    tags: ['v*']
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g., v0.1.0)'
        required: true
        type: string

env:
  CARGO_TERM_COLOR: always

permissions:
  contents: write

jobs:
  test:
    name: Test and Validate
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt, clippy

    - name: Cache cargo dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-test-
          ${{ runner.os }}-cargo-

    - name: Check code formatting
      run: cargo fmt -- --check

    - name: Run clippy
      run: cargo clippy --all-targets --all-features -- -D warnings

    - name: Run tests
      run: cargo test --all-features

    - name: Test documentation
      run: cargo doc --no-deps --all-features

    - name: Check for security vulnerabilities
      run: |
        cargo install cargo-audit
        cargo audit

  verify:
    name: Verify Release
    runs-on: ubuntu-latest
    needs: test
    outputs:
      version: ${{ steps.version.outputs.version }}
      cargo_version: ${{ steps.version.outputs.cargo_version }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

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

    - name: Verify version consistency
      id: version
      run: |
        chmod +x scripts/verify-version.sh
        if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
          ./scripts/verify-version.sh "${{ github.event.inputs.version }}"
        else
          ./scripts/verify-version.sh
        fi

        # 输出版本信息供后续job使用
        echo "version=${RELEASE_VERSION}" >> $GITHUB_OUTPUT
        echo "cargo_version=${CARGO_VERSION}" >> $GITHUB_OUTPUT

    - name: Verify package can be built
      run: cargo build --release

    - name: Verify package can be packaged
      run: |
        cargo package --allow-dirty
        echo "Package verification successful"

    - name: Check publish readiness (dry run)
      run: |
        cargo publish --dry-run --allow-dirty
        echo "Publish dry run successful"

  github-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: verify
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

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

    - name: Cache cargo dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-release-
          ${{ runner.os }}-cargo-

    - name: Generate changelog
      id: changelog
      run: |
        echo "## Changes in ${{ needs.verify.outputs.version }}" > CHANGELOG.md
        echo "" >> CHANGELOG.md

        # 尝试从Git提交生成变更日志
        if [ -n "$(git tag --list | tail -2 | head -1)" ]; then
          PREV_TAG=$(git tag --list | tail -2 | head -1)
          echo "### Commits since $PREV_TAG:" >> CHANGELOG.md
          git log --oneline $PREV_TAG..HEAD >> CHANGELOG.md
        else
          echo "### Initial release" >> CHANGELOG.md
          echo "- First release of wim-parser library" >> CHANGELOG.md
        fi

        echo "changelog<<EOF" >> $GITHUB_OUTPUT
        cat CHANGELOG.md >> $GITHUB_OUTPUT
        echo "EOF" >> $GITHUB_OUTPUT

    - name: Create GitHub Release
      uses: softprops/action-gh-release@v2
      with:
        tag_name: ${{ needs.verify.outputs.version }}
        name: Release ${{ needs.verify.outputs.version }}
        body: ${{ steps.changelog.outputs.changelog }}
        draft: false
        prerelease: false
        generate_release_notes: true
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  crates-publish:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    needs: [verify, github-release]
    environment: crates-io
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

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

    - name: Cache cargo dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-publish-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-publish-
          ${{ runner.os }}-cargo-

    - name: Publish to crates.io
      run: |
        echo "Publishing wim-parser version ${{ needs.verify.outputs.cargo_version }} to crates.io"
        cargo publish --token ${{ secrets.CRATES_TOKEN }} --allow-dirty
        echo "✅ Successfully published to crates.io!"

    - name: Verify publication
      run: |
        echo "Waiting for crates.io to index the new version..."
        sleep 30

        # 验证发布是否成功
        if cargo search wim-parser | grep -q "${{ needs.verify.outputs.cargo_version }}"; then
          echo "✅ Version ${{ needs.verify.outputs.cargo_version }} is now available on crates.io"
        else
          echo "⚠️  Version may still be indexing on crates.io"
        fi

  notify:
    name: Notify Release Complete
    runs-on: ubuntu-latest
    needs: [verify, github-release, crates-publish]
    if: always()

    steps:
    - name: Release Summary
      run: |
        echo "## 🎉 Release Summary"
        echo "- Version: ${{ needs.verify.outputs.version }}"
        echo "- GitHub Release: ${{ needs.github-release.result }}"
        echo "- Crates.io Publish: ${{ needs.crates-publish.result }}"

        if [ "${{ needs.github-release.result }}" = "success" ] && [ "${{ needs.crates-publish.result }}" = "success" ]; then
          echo "✅ Release completed successfully!"
          echo "📦 Package is now available at: https://crates.io/crates/wim-parser"
          echo "📋 Release notes: https://github.com/${{ github.repository }}/releases/tag/${{ needs.verify.outputs.version }}"
        else
          echo "❌ Release completed with issues. Please check the logs above."
        fi