context7-cli 0.2.7

Search library documentation from your terminal — zero runtime, bilingual (EN/PT), multi-key rotation
Documentation
name: Release

on:
  workflow_dispatch:
    inputs:
      dry_run:
        description: 'Dry run (não publica de verdade)'
        required: false
        default: 'true'
        type: boolean

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0

jobs:
  validate:
    name: Validar antes de publicar
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Instalar toolchain Rust estável
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache de dependências Rust
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ubuntu-stable-release

      - name: Verificar formatação
        run: cargo fmt --all --check

      - name: Clippy sem warnings
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Testes completos
        run: cargo test --all-features

      - name: Documentação sem warnings
        run: cargo doc --no-deps --all-features
        env:
          RUSTDOCFLAGS: -D warnings

      - name: Dry-run de publicação
        run: cargo publish --dry-run

  build-matrix:
    name: Build release (${{ matrix.target }})
    needs: validate
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            binary_name: context7
            archive_ext: tar.gz
          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            binary_name: context7
            archive_ext: tar.gz
          - os: macos-latest
            target: aarch64-apple-darwin
            binary_name: context7
            archive_ext: tar.gz
          - os: macos-13
            target: x86_64-apple-darwin
            binary_name: context7
            archive_ext: tar.gz
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            binary_name: context7.exe
            archive_ext: zip
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Instalar toolchain Rust estável
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Instalar musl-tools (Linux musl)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Cache de dependências Rust
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ${{ matrix.os }}-${{ matrix.target }}-release

      - name: Build release
        run: cargo build --release --target ${{ matrix.target }}

      - name: Empacotar artefato (Linux/macOS)
        if: matrix.archive_ext == 'tar.gz'
        shell: bash
        run: |
          ARCHIVE="context7-${{ matrix.target }}.tar.gz"
          tar -czf "$ARCHIVE" -C "target/${{ matrix.target }}/release" "${{ matrix.binary_name }}"
          echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV"

      - name: Empacotar artefato (Windows)
        if: matrix.archive_ext == 'zip'
        shell: pwsh
        run: |
          $archive = "context7-${{ matrix.target }}.zip"
          Compress-Archive -Path "target/${{ matrix.target }}/release/${{ matrix.binary_name }}" -DestinationPath $archive
          "ARCHIVE=$archive" | Out-File -FilePath $env:GITHUB_ENV -Append

      - name: Upload artefato de build
        uses: actions/upload-artifact@v4
        with:
          name: context7-${{ matrix.target }}
          path: context7-${{ matrix.target }}.${{ matrix.archive_ext }}
          retention-days: 7
          if-no-files-found: error

  macos-universal:
    name: Universal Binary macOS (lipo)
    needs: build-matrix
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Baixar artefato aarch64-apple-darwin
        uses: actions/download-artifact@v4
        with:
          name: context7-aarch64-apple-darwin
          path: artifacts/aarch64

      - name: Baixar artefato x86_64-apple-darwin
        uses: actions/download-artifact@v4
        with:
          name: context7-x86_64-apple-darwin
          path: artifacts/x86_64

      - name: Extrair binários
        run: |
          tar -xzf artifacts/aarch64/context7-aarch64-apple-darwin.tar.gz -C artifacts/aarch64
          tar -xzf artifacts/x86_64/context7-x86_64-apple-darwin.tar.gz -C artifacts/x86_64

      - name: Criar Universal Binary com lipo
        run: |
          lipo -create \
            artifacts/aarch64/context7 \
            artifacts/x86_64/context7 \
            -output context7-universal
          # Verificar que o universal binary contém ambas as arquiteturas
          lipo -info context7-universal

      - name: Assinar Universal Binary (adhoc ou Developer ID)
        env:
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
        run: |
          if [ -z "${APPLE_TEAM_ID:-}" ]; then
            # Caminho sem certificado Apple Developer: assinatura adhoc
            codesign --sign - --force context7-universal
            echo "Assinatura adhoc aplicada (sem certificado Apple Developer)"
          else
            # Caminho com certificado Developer ID Application
            codesign --sign "Developer ID Application: $APPLE_TEAM_ID" \
              --options runtime \
              --force \
              context7-universal
            # Empacotar para submissão de notarização
            zip context7-universal-notarize.zip context7-universal
            # Submeter para o serviço de notarização da Apple
            xcrun notarytool submit context7-universal-notarize.zip \
              --apple-id "$APPLE_ID" \
              --password "$APPLE_APP_PASSWORD" \
              --team-id "$APPLE_TEAM_ID" \
              --wait
            # Staple do ticket de notarização no binário
            xcrun stapler staple context7-universal || true
          fi

      - name: Empacotar Universal Binary
        run: |
          tar -czf context7-macos-universal.tar.gz context7-universal

      - name: Upload Universal Binary
        uses: actions/upload-artifact@v4
        with:
          name: context7-macos-universal
          path: context7-macos-universal.tar.gz
          retention-days: 7
          if-no-files-found: error

  publish-github-release:
    name: Publicar GitHub Release
    needs: [validate, build-matrix, macos-universal]
    runs-on: ubuntu-latest
    if: ${{ github.event.inputs.dry_run == 'false' }}
    permissions:
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Baixar todos os artefatos de build
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Listar artefatos baixados
        shell: bash
        run: |
          shopt -s globstar nullglob
          printf '%s\n' artifacts/**/* | sort

      - name: Extrair versão do Cargo.toml
        run: |
          VERSION=$(rg -m1 -o '^version\s*=\s*"(.+)"' Cargo.toml -r '$1')
          echo "VERSION=$VERSION" >> "$GITHUB_ENV"
          echo "Versão detectada: $VERSION"

      - name: Publicar GitHub Release com artefatos
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ env.VERSION }}
          name: "context7-cli v${{ env.VERSION }}"
          body: |
            ## context7-cli v${{ env.VERSION }}

            Pesquise documentação de qualquer biblioteca diretamente do terminal.
            Search any library's documentation directly from your terminal.

            ### Instalação / Installation

            **Via cargo (recomendado / recommended):**
            ```bash
            cargo install context7-cli
            ```

            **Download direto / Direct download:**

            | Plataforma / Platform | Arquivo / File |
            |---|---|
            | Linux x86_64 (glibc) | `context7-x86_64-unknown-linux-gnu.tar.gz` |
            | Linux x86_64 (musl/Alpine) | `context7-x86_64-unknown-linux-musl.tar.gz` |
            | macOS Universal (arm64+x86_64) | `context7-macos-universal.tar.gz` |
            | macOS arm64 | `context7-aarch64-apple-darwin.tar.gz` |
            | macOS x86_64 | `context7-x86_64-apple-darwin.tar.gz` |
            | Windows x86_64 | `context7-x86_64-pc-windows-msvc.zip` |
          draft: false
          prerelease: false
          files: |
            artifacts/**/*.tar.gz
            artifacts/**/*.zip
          generate_release_notes: false
          fail_on_unmatched_files: false

  publish-crates-io:
    name: Publicar no crates.io
    needs: [validate, build-matrix]
    runs-on: ubuntu-latest
    if: ${{ github.event.inputs.dry_run == 'false' }}
    permissions:
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Instalar toolchain Rust estável
        uses: dtolnay/rust-toolchain@stable

      - name: Cache de dependências Rust
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ubuntu-stable-publish

      - name: Publicar no crates.io
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}