name: Release
on:
push:
tags:
- 'v*'
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-latest
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@v7
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@v8
with:
name: context7-aarch64-apple-darwin
path: artifacts/aarch64
- name: Baixar artefato x86_64-apple-darwin
uses: actions/download-artifact@v8
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: Smoke test Universal Binary
run: |
chmod +x context7-universal
./context7-universal --version
./context7-universal --help
- name: Empacotar Universal Binary
run: |
tar -czf context7-macos-universal.tar.gz context7-universal
- name: Upload Universal Binary
uses: actions/upload-artifact@v7
with:
name: context7-macos-universal
path: context7-macos-universal.tar.gz
retention-days: 7
if-no-files-found: error
build-flatpak:
name: Build Flatpak
needs: validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Instalar dependências do Flatpak e flatpak-builder
run: |
sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
- name: Adicionar remote Flathub (para SDK)
run: |
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
sudo flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 org.freedesktop.Sdk.Extension.rust-stable//24.08
- name: Build Flatpak bundle
run: |
flatpak-builder \
--repo=flatpak-repo \
--force-clean \
flatpak-build \
packaging/flatpak/br.com.daniloaguiar.context7-cli.yaml
flatpak build-bundle \
flatpak-repo \
context7-cli.flatpak \
br.com.daniloaguiar.context7-cli
- name: Upload artefato Flatpak
uses: actions/upload-artifact@v7
with:
name: context7-flatpak
path: context7-cli.flatpak
retention-days: 7
if-no-files-found: error
build-snap:
name: Build Snap
needs: validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Copiar snapcraft.yaml para raiz do repositório
run: cp packaging/snap/snapcraft.yaml .
- name: Build Snap package
uses: snapcore/action-build@v1
id: build-snap
with:
snapcraft-args: --destructive-mode
- name: Upload artefato Snap
uses: actions/upload-artifact@v7
with:
name: context7-snap
path: ${{ steps.build-snap.outputs.snap }}
retention-days: 7
if-no-files-found: error
publish-github-release:
name: Publicar GitHub Release
needs: [validate, build-matrix, macos-universal, build-flatpak, build-snap]
runs-on: ubuntu-latest
if: |
always() &&
(github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false')) &&
needs.validate.result == 'success' &&
needs.build-matrix.result == 'success' &&
needs.macos-universal.result == 'success'
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Instalar ripgrep
run: sudo apt-get update && sudo apt-get install -y ripgrep
- name: Baixar todos os artefatos de build
uses: actions/download-artifact@v8
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
shell: bash
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` |
| Flatpak (Linux) | `context7-cli.flatpak` |
| Snap (Linux) | `context7-cli_*.snap` |
draft: false
prerelease: false
files: |
artifacts/**/*.tar.gz
artifacts/**/*.zip
artifacts/**/*.flatpak
artifacts/**/*.snap
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_name == 'push' || (github.event_name == 'workflow_dispatch' && 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 }}