CLI: CI Integration

Use the Keito CLI in CI by setting credentials as secrets and running commands with --json.

Required environment variables:

VariableDescription
KEITO_API_KEYkto_... API key stored as a CI secret
KEITO_ACCOUNT_IDCompany ID from Settings > API & Developers > Company ID

GitHub Actions

This pattern keeps the timer lifecycle inside one shell step so cleanup can run reliably:

name: AI Code Review
on: [pull_request]

jobs:
  review:
    runs-on: ubuntu-latest
    env:
      KEITO_API_KEY: ${{ secrets.KEITO_API_KEY }}
      KEITO_ACCOUNT_ID: ${{ secrets.KEITO_ACCOUNT_ID }}
      KEITO_PROJECT_ID: ${{ vars.KEITO_PROJECT_ID }}
      KEITO_TASK_ID: ${{ vars.KEITO_TASK_ID }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - name: Install Keito CLI
        shell: bash
        run: |
          curl --proto '=https' --tlsv1.2 -LsSf \
            https://github.com/osodevops/keito-cli/releases/latest/download/keito-installer.sh | sh
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"

      - name: Run review with Keito tracking
        shell: bash
        run: |
          set -euo pipefail
          export PATH="$HOME/.cargo/bin:$PATH"

          STARTED=0
          cleanup() {
            status=$?
            if [ "$STARTED" = "1" ]; then
              if [ "$status" -eq 0 ]; then
                keito time stop \
                  --notes "AI code review for PR #${{ github.event.pull_request.number }}" \
                  --json || true
              else
                keito time stop --discard --json || true
              fi
            fi
          }
          trap cleanup EXIT

          keito auth status --json
          keito time start \
            --project "$KEITO_PROJECT_ID" \
            --task "$KEITO_TASK_ID" \
            --notes "AI code review for PR #${{ github.event.pull_request.number }}" \
            --json
          STARTED=1

          ./scripts/ai-review.sh

GitLab CI

ai-review:
  stage: review
  variables:
    KEITO_API_KEY: $KEITO_API_KEY
    KEITO_ACCOUNT_ID: $KEITO_ACCOUNT_ID
    KEITO_PROJECT_ID: $KEITO_PROJECT_ID
    KEITO_TASK_ID: $KEITO_TASK_ID
  before_script:
    - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/osodevops/keito-cli/releases/latest/download/keito-installer.sh | sh
    - export PATH="$HOME/.cargo/bin:$PATH"
  script:
    - |
      set -euo pipefail
      STARTED=0
      cleanup() {
        status=$?
        if [ "$STARTED" = "1" ]; then
          if [ "$status" -eq 0 ]; then
            keito time stop --notes "AI review for $CI_COMMIT_SHORT_SHA" --json || true
          else
            keito time stop --discard --json || true
          fi
        fi
      }
      trap cleanup EXIT

      keito auth status --json
      keito time start --project "$KEITO_PROJECT_ID" --task "$KEITO_TASK_ID" --json
      STARTED=1
      ./scripts/ai-review.sh

Successful vs Failed Jobs

For successful jobs, stop the timer normally:

keito time stop --notes "Job completed" --json

For failed jobs that should not be billed, discard the timer:

keito time stop --discard --json

If failed automation should still be billed, stop normally and include failure context in the notes instead of discarding.

CI Notes

  • Store API keys in CI secrets. Never commit them.
  • Use project and task IDs in CI variables to avoid name ambiguity.
  • Run keito auth status --json before starting work.
  • Use --json for all CI commands.
  • The current CLI tracks time only. Log LLM token costs through the API, SDKs, or Keito web app.