Add to CI
This quickstart adds linting to every PR and behavioral evaluation to trusted changes.
vally lint is a fast, free static check — no agent needed. It validates your SKILL.md files (skill definitions that describe your agent’s capabilities) and your eval.yaml specs for config errors. Run it on every PR as a first gate, then use vally eval for full behavioral checks on trusted code.
-
Add the lint step (every PR)
Create
.github/workflows/skill-lint.yml:.github/workflows/skill-lint.yml name: Skill Linton:pull_request:paths:- "**/SKILL.md"- "**/*.yaml"jobs:lint:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with:node-version: "22"check-latest: true- run: npm install -g @microsoft/vally-cli- name: Lint skillsrun: vally lint .- name: Validate eval specsrun: vally lint --eval-spec evals/hello/eval.yaml --strictThis lint pass catches:
- Invalid SKILL.md format (name, description, frontmatter)
- Broken file references
-
Add behavioral evals
Run agent-level evals before merging branches from the same repository and after merging fork contributions. First, configure one of these authentication options:
Recommended: GitHub Actions token
- For an organization-owned repository, ask an organization owner to enable Allow use of Copilot CLI billed to the organization.
- Grant the workflow
copilot-requests: writepermission. - Pass
${{ github.token }}to Vally asGITHUB_TOKEN, as shown in the workflow below.
The built-in token is short-lived, authenticates both the default
copilot-sdkexecutor and LLM judges, and does not require a repository secret. See GitHub’s Copilot CLI in GitHub Actions setup..github/workflows/skill-eval.yml name: Skill Evalon:pull_request:paths:- "**/SKILL.md"- "**/eval.yaml"push:branches: [main]paths:- "**/SKILL.md"- "**/eval.yaml"workflow_dispatch:permissions:contents: readcopilot-requests: writejobs:eval:# Fork PRs cannot receive Copilot write permission or repository secrets.if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repositoryruns-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with:node-version: "22"check-latest: true- run: npm install -g @microsoft/vally-cli- name: Run evalsrun: |vally eval \--eval-spec evals/hello/eval.yaml \--skill-dir . \--require-pass \--output-dir ./resultsenv:GITHUB_TOKEN: ${{ github.token }}- name: Upload trajectoriesif: always()uses: actions/upload-artifact@v4with:name: eval-resultspath: ./results/Fallback: Fine-grained personal access token
If your organization cannot enable the Copilot CLI policy:
- Create a fine-grained personal access token with Account permissions > Copilot Requests.
- Save it as a GitHub Actions repository secret named
COPILOT_CLI_TOKEN. - Replace the
envblock in the Run evals step with:
env:GH_TOKEN: ${{ secrets.COPILOT_CLI_TOKEN }}GITHUB_COPILOT_API_TOKEN: ${{ secrets.COPILOT_CLI_TOKEN }}The same secret is mapped twice because the default executor reads
GH_TOKEN, while LLM judges readGITHUB_COPILOT_API_TOKEN.This fallback also skips fork PRs because repository secrets are not provided to them; the
pushtrigger runs their eval after merge. -
Use exit codes for gating
Both
lintandevalsetprocess.exitCode = 1on errors, so GitHub Actions will automatically mark the step as failed.vally lint→ exits 1 if any skill fails validationvally eval→ exits 1 for grader, execution, configuration, or tooling errors. Add--require-passto also exit 1 when a valid eval verdict fails.
Running Specific Suites
Section titled “Running Specific Suites”Define suites in .vally.yaml to run different eval subsets in different CI contexts:
suites: ci-gate: filter: { priority: [p0, p1] } nightly: filter: { priority: [p0, p1, p2] }# .github/workflows/ci.yml — fast suite on every PR- name: Run CI gate evals run: vally eval --suite ci-gate --require-pass
# .github/workflows/nightly.yml — comprehensive nightly run- name: Run nightly evals run: vally eval --suite nightlyThe PR suite uses --require-pass to gate on valid failing verdicts. The nightly suite omits it so
valid failures are reported without failing the scheduled workflow; operational errors still fail
both commands.
Next steps
Section titled “Next steps”- Runtime setup — executor and credential options for local runs and CI
- Grader taxonomy — pick graders by determinism and cost
- Writing eval specs — design better stimuli