← Files CerebriumARCHIVED FILE

.github/workflows/skill-drift.yml

4.5 KB · Sep 30, 2026 · 23:15 UTC

↓ Download file

name: skill-drift

# Compares what the Cerebrium CLI can actually do against what the skill claims
# it can do, and says so when the two diverge.
#
# The comparison is always against the latest RELEASED tag of
# CerebriumAI/cerebrium, never its default branch. A flag can exist on the
# default branch and be in no release yet, and an agent that follows the skill
# runs the released binary. Pointing this at the default branch turns those
# cases into a clean pass, which is worse than not checking at all.

on:
  schedule:
    - cron: "17 6 * * 1"
  workflow_dispatch:
  pull_request:

permissions:
  contents: read

jobs:
  drift:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: stable

      - name: Resolve the latest released CLI tag
        id: cli
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -euo pipefail
          tag=$(gh api repos/CerebriumAI/cerebrium/releases/latest --jq .tag_name)
          [ -n "$tag" ] || { echo "no released tag found"; exit 1; }
          echo "tag=$tag" >> "$GITHUB_OUTPUT"
          echo "comparing against CLI $tag"

      - name: Check out the CLI at that tag
        env:
          TAG: ${{ steps.cli.outputs.tag }}
        run: |
          set -euo pipefail
          git clone --quiet --depth 1 --branch "$TAG" \
            https://github.com/CerebriumAI/cerebrium.git cli

      - name: Extract the CLI surface
        run: |
          set -euo pipefail
          # surfacedump lives inside the module so it can import internal/... .
          # cobra and pflag are already required there, so go.mod and go.sum are
          # untouched and nothing is ever pushed back to that repository.
          mkdir -p cli/skilldrift/surfacedump
          cp tools/surfacedump/main.go cli/skilldrift/surfacedump/main.go
          (cd cli && go run ./skilldrift/surfacedump) > surface.json
          dirty=$(git -C cli status --porcelain | grep -v '^?? skilldrift/$' || true)
          if [ -n "$dirty" ]; then
            echo "the CLI checkout was modified, which must never happen:"
            echo "$dirty"
            exit 1
          fi

      - name: Compare the CLI surface against the skill
        id: drift
        env:
          TAG: ${{ steps.cli.outputs.tag }}
        run: |
          set -uo pipefail
          python3 tools/check_drift.py \
            --surface surface.json \
            --skills skills \
            --ref "$TAG" | tee drift-report.txt
          echo "exit=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"

      - name: Fail the check when a pull request drifts
        if: github.event_name == 'pull_request'
        env:
          TAG: ${{ steps.cli.outputs.tag }}
          DRIFT_EXIT: ${{ steps.drift.outputs.exit }}
        run: |
          set -euo pipefail
          [ "$DRIFT_EXIT" = "0" ] || {
            echo "::error::the skill and CLI $TAG disagree, see the report above"
            exit 1
          }

      # On a schedule the point is to raise the divergence for a human to
      # resolve, so the run opens a pull request whose diff is the report and
      # whose body is the summary. A reviewer edits the skill on the same
      # branch and drops the report before merging.
      - name: Open a pull request for the drift
        if: github.event_name != 'pull_request' && steps.drift.outputs.exit != '0'
        env:
          GH_TOKEN: ${{ github.token }}
          TAG: ${{ steps.cli.outputs.tag }}
        run: |
          set -euo pipefail
          branch="skill-drift/${TAG}"
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git checkout -B "$branch"
          {
            echo "# Skill drift against CLI ${TAG}"
            echo
            echo "Written by the skill-drift workflow. Edit the skill on this branch and delete"
            echo "this file before merging."
            echo
            echo '```'
            cat drift-report.txt
            echo '```'
          } > tools/drift-report.md
          git add tools/drift-report.md
          git commit -m "Report skill drift against CLI ${TAG}"
          git push --force origin "$branch"
          if [ -z "$(gh pr list --head "$branch" --state open --json number --jq '.[].number')" ]; then
            gh pr create --head "$branch" \
              --title "Skill drift against CLI ${TAG}" \
              --body-file tools/drift-report.md
          fi

SHA-256: c2cfbdd0fdbf55569646c34e47f851b054f0c737d0cfee6515c4cf6cdd54019f