drission 0.5.1

Rust 反检测浏览器自动化与身份治理引擎:账号池指纹准入/漂移/lifecycle 审计,内置 ddddocr OCR 与滑块缺口识别,默认 Chrome/CDP、可选 Camoufox、Cloudflare 过盾、高并发爬虫与 XHR 监听拦截。Anti-detect browser automation and browser identity governance in Rust.
Documentation
name: Release drs binaries

# Build the `drs` CLI/MCP binary for macOS / Linux / Windows and attach the
# archives to a GitHub Release. This is what makes `drs` installable WITHOUT a
# Rust toolchain (see install/drs-install.sh). Triggered by pushing a `v*` tag,
# or manually via workflow_dispatch (provide a tag that already exists).
on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      tag:
        description: "Existing tag to build & release (e.g. v0.3.2)"
        required: true

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always
  # crates.io mirror is not used in CI; keep default registry.

jobs:
  build:
    name: build ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: aarch64-apple-darwin
            os: macos-14
            cross: false
          - target: x86_64-apple-darwin
            os: macos-14
            cross: false
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            cross: true
          - target: aarch64-unknown-linux-musl
            os: ubuntu-latest
            cross: true
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            cross: false
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - uses: Swatinem/rust-cache@v2
        with:
          key: release-${{ matrix.target }}

      # reqwest (a `drission` dep) pulls rustls + aws-lc-sys, whose x86_64
      # assembly needs nasm on Windows/MSVC. cmake ships on the runner.
      - name: Install nasm (Windows aws-lc-sys)
        if: runner.os == 'Windows'
        uses: ilammy/setup-nasm@v1

      - name: Install cross (musl targets)
        if: matrix.cross
        uses: taiki-e/install-action@v2
        with:
          tool: cross

      # Build only the `drs` binary with the default (cdp) backend: this is the
      # browser MCP/CLI gateway. OCR/slider/impersonate stay source-only builds.
      - name: Build (cross)
        if: matrix.cross
        run: cross build --release --target ${{ matrix.target }} -p drission-cli --bin drs

      - name: Build (native)
        if: ${{ !matrix.cross }}
        run: cargo build --release --target ${{ matrix.target }} -p drission-cli --bin drs

      - name: Package (unix)
        if: runner.os != 'Windows'
        shell: bash
        run: |
          BIN="target/${{ matrix.target }}/release/drs"
          test -f "$BIN" || { echo "missing $BIN"; exit 1; }
          mkdir -p dist
          tar -czf "dist/drs-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" drs
          ( cd dist && shasum -a 256 "drs-${{ matrix.target }}.tar.gz" > "drs-${{ matrix.target }}.tar.gz.sha256" )

      - name: Package (windows)
        if: runner.os == 'Windows'
        shell: pwsh
        run: |
          $bin = "target/${{ matrix.target }}/release/drs.exe"
          if (-not (Test-Path $bin)) { throw "missing $bin" }
          New-Item -ItemType Directory -Force -Path dist | Out-Null
          Compress-Archive -Path $bin -DestinationPath "dist/drs-${{ matrix.target }}.zip" -Force
          (Get-FileHash "dist/drs-${{ matrix.target }}.zip" -Algorithm SHA256).Hash | Out-File -Encoding ascii "dist/drs-${{ matrix.target }}.zip.sha256"

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: drs-${{ matrix.target }}
          path: dist/*
          if-no-files-found: error

  release:
    name: publish GitHub Release
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true

      - name: List artifacts
        run: ls -R dist

      - name: Create / update release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ github.event.inputs.tag || github.ref_name }}
          name: ${{ github.event.inputs.tag || github.ref_name }}
          generate_release_notes: true
          files: |
            dist/drs-*.tar.gz
            dist/drs-*.tar.gz.sha256
            dist/drs-*.zip
            dist/drs-*.zip.sha256

  # Mirror the tag + prebuilt drs assets to GitCode so install/drs-install.sh can
  # fall back to gitcode.com/Roufsi/drission-rs/releases/download/<tag>/...
  mirror-gitcode:
    name: mirror release to GitCode
    needs: release
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true

      - name: Push tag to GitCode
        env:
          GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
        run: |
          if [ -z "${GITCODE_TOKEN:-}" ]; then
            echo "::notice::GITCODE_TOKEN not set — skip GitCode git push."
            exit 0
          fi
          git remote add gitcode "https://oauth2:${GITCODE_TOKEN}@gitcode.com/Roufsi/drission-rs.git"
          git push gitcode "${{ github.ref_name }}:refs/tags/${{ github.ref_name }}"
          git push gitcode HEAD:main

      - name: Create GitCode release + upload assets
        env:
          GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
          TAG: ${{ github.ref_name }}
        run: |
          if [ -z "${GITCODE_TOKEN:-}" ]; then
            echo "::notice::GITCODE_TOKEN not set — skip GitCode release upload."
            echo "Install script still works via GitHub Releases (primary)."
            exit 0
          fi
          set -euo pipefail
          API="https://api.gitcode.com/api/v5/repos/Roufsi/drission-rs/releases"
          BODY=$(jq -n --arg tag "$TAG" '{tag_name:$tag,name:$tag,body:"Prebuilt drs CLI/MCP binaries (mirrored from GitHub Release)",draft:false,prerelease:false}')
          RESP=$(curl -fsS -X POST "$API?access_token=${GITCODE_TOKEN}" -H "Content-Type: application/json" -d "$BODY" || true)
          if echo "$RESP" | jq -e '.id' >/dev/null 2>&1; then
            RID=$(echo "$RESP" | jq -r '.id')
          else
            echo "Release may already exist, fetching by tag..."
            RID=$(curl -fsS "$API/tags/$TAG?access_token=${GITCODE_TOKEN}" | jq -r '.id')
          fi
          for f in dist/drs-*; do
            [ -f "$f" ] || continue
            echo "Uploading $(basename "$f")..."
            curl -fsS -X POST \
              "https://api.gitcode.com/api/v5/repos/Roufsi/drission-rs/releases/${RID}/assets?access_token=${GITCODE_TOKEN}&name=$(basename "$f")" \
              -H "Content-Type: application/octet-stream" \
              --data-binary "@$f"
          done