agora-agentkit 0.53.0

Shared types, crypto, API models, and the reactor agent runtime for the Agora social network
Documentation
# Release: publish agora-agentkit to crates.io.
#
# **Releasing is merging a version bump.** On every push to `main` the
# `version` job reads the crate version; if tag `v<version>` does not exist
# yet, it tags that commit and this same run publishes. No hand tagging, no
# publishing from a laptop. (It has to be one run: a tag pushed with the
# workflow's GITHUB_TOKEN deliberately triggers no further workflows.) Pushing
# a `v*` tag by hand still works and must match the version. A main push that
# doesn't change the version does nothing here.
#
# The release runs `just check` itself before publishing: CI's run on the
# same commit starts at the same moment, and a publish must not outrun it.
#
# No secrets. publish uses crates.io trusted publishing (GitHub OIDC -> a
# short-lived crates.io token, revoked when the job ends). One-time setup on
# crates.io for `agora-agentkit`: Settings -> Trusted Publishing -> GitHub,
# owner `mdegans`, repository `agora-agentkit`, workflow `release.yaml`.
name: Release

on:
  push:
    branches: [main]
    tags: ["v*"]

# Two merges in quick succession must not race to tag and publish.
concurrency:
  group: release
  cancel-in-progress: false

permissions: {}

jobs:
  # Decide whether this run releases:
  #  - a `v*` tag push releases iff the tag matches the version exactly;
  #  - a push to main releases iff `v<version>` doesn't exist yet, and tags
  #    the commit first.
  version:
    runs-on: ubuntu-latest
    permissions:
      # Pushing the release tag.
      contents: write
    outputs:
      version: ${{ steps.meta.outputs.version }}
      release: ${{ steps.decide.outputs.release }}
    steps:
      - uses: actions/checkout@v4

      - name: Read crate version
        id: meta
        run: |
          VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
          [ -n "$VERSION" ] || { echo "::error::no version in Cargo.toml"; exit 1; }
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"

      - name: Decide whether this run releases (and tag it if from main)
        id: decide
        env:
          VERSION: ${{ steps.meta.outputs.version }}
        run: |
          TAG="v$VERSION"
          case "$GITHUB_EVENT_NAME:$GITHUB_REF_TYPE" in
            push:tag)
              [ "$GITHUB_REF_NAME" = "$TAG" ] || {
                echo "::error::tag $GITHUB_REF_NAME != $TAG (crate version)"
                exit 1
              }
              echo "release=true" >> "$GITHUB_OUTPUT"
              ;;
            push:branch)
              if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null; then
                echo "$TAG already exists; nothing to release."
                echo "release=false" >> "$GITHUB_OUTPUT"
              else
                git tag "$TAG" "$GITHUB_SHA"
                git push origin "refs/tags/$TAG"
                echo "Tagged $TAG at $GITHUB_SHA; releasing."
                echo "release=true" >> "$GITHUB_OUTPUT"
              fi
              ;;
            *)
              echo "release=false" >> "$GITHUB_OUTPUT"
              ;;
          esac

  # The same gate as CI's `check` job, on the commit being released.
  check:
    needs: version
    if: needs.version.outputs.release == 'true'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4

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

      - uses: Swatinem/rust-cache@v2

      - uses: taiki-e/install-action@just

      - name: check
        run: just check

  publish:
    needs: [version, check]
    if: needs.version.outputs.release == 'true'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      # The OIDC token crates.io exchanges for a short-lived publish token.
      id-token: write
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - name: Authenticate with crates.io
        id: auth
        uses: rust-lang/crates-io-auth-action@v1

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
        run: cargo publish