research-agent 0.2.4

Long-term research assistant: index papers, articles, and PDFs
Documentation
# Post-release publishing that cargo-dist does not own. Tag-scoped; a green
# no-op until its credential secret is configured:
#   - CARGO_REGISTRY_TOKEN → cargo publish to crates.io (the name `cargo
#     login` itself uses)
# Homebrew tap publishing stays with cargo-dist's own
# publish-homebrew-formula job in release.yml — do not duplicate it here.
# The crate is only published after EVERY check run on the tag commit (CI
# and the Release build itself) has finished green.
# Secrets are repository settings; see AGENTS.md "Release".
name: Release extras

on:
  push:
    tags:
      - "**[0-9]+.[0-9]+.[0-9]+*"
  # manual re-run for an existing tag (e.g. after rotating a credential);
  # dispatch from main and pass --field tag=vX.Y.Z so the fixed workflow
  # file runs while the crate content resolves from the tag
  workflow_dispatch:
    inputs:
      tag:
        description: "Tag to publish (defaults to the dispatched ref)"
        required: false
        type: string

permissions:
  contents: read

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

jobs:
  wait-checks:
    name: Wait for CI and Release checks on the tag
    runs-on: ubuntu-latest
    env:
      TAG_REF: ${{ inputs.tag || github.ref_name }}
    steps:
      - name: Block until every workflow run on the tag commit is green
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          repo="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
          # an annotated tag resolves to the tag object — peel to the commit
          sha="$(git ls-remote "$repo" "refs/tags/${TAG_REF}^{}" | cut -f1)"
          [ -n "$sha" ] || sha="$(git ls-remote "$repo" "${TAG_REF}" | cut -f1)"
          echo "waiting on workflow runs for ${TAG_REF} (${sha})"
          for i in $(seq 1 120); do
            # poll workflow runs on the tag commit, ignoring this workflow —
            # our own runs would never be "success" while we wait on them
            out="$(gh api "repos/${GITHUB_REPOSITORY}/actions/runs?head_sha=${sha}" \
              --jq '.workflow_runs[] | select(.name != "Release extras") |
                    "\(.name) \(.status)/\(.conclusion // "pending")"' | sort -u)"
            echo "attempt ${i}:"
            echo "$out"
            case "$out" in
              *"in_progress"*|*"queued"*|*"pending"*|*"waiting"*|*"requested"*) sleep 30; continue ;;
            esac
            echo "$out" | grep -q '^Release ' || { sleep 30; continue; }
            echo "$out" | grep -q '^CI '       || { sleep 30; continue; }
            if printf '%s\n' "$out" | grep -qv 'completed/success'; then
              echo "a workflow run did not succeed:" "$out" >&2
              exit 1
            fi
            exit 0
          done
          echo "workflow runs did not settle within 60 minutes" >&2
          exit 1

  publish-crates:
    name: Publish to crates.io
    needs: [wait-checks]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ inputs.tag || github.ref_name }}
      - uses: dtolnay/rust-toolchain@stable
      - name: Publish
        env:
          CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        if: ${{ env.CRATES_TOKEN != '' }}
        run: cargo publish --locked --token "$CRATES_TOKEN"