Skip to content

Guide Yield release decisions (#65) #151

Guide Yield release decisions (#65)

Guide Yield release decisions (#65) #151

Workflow file for this run

name: Verify Yield
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
concurrency:
group: verify-yield-${{ github.ref }}
cancel-in-progress: true
jobs:
format:
name: Repository formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache: true
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
cache: npm
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- run: npm ci --ignore-scripts
- run: python -m pip install uv==0.12.3
- run: npm run format:check
go:
name: Go and agent registration (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache: true
- run: go test ./cmd/yskill
- run: go test ./...
- run: go build ./...
release:
name: Release and package controls
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
cache: npm
- run: npm ci --ignore-scripts
- run: npm run test:release
- run: node scripts/check-release-control.mjs
selfhost:
name: Published SDK self-hosting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
cache: npm
- run: npm ci --ignore-scripts
- run: npm run prepare:selfhost
- run: npm run test:selfhost
- run: npm exec -- yskill doctor skills/release-yield --root . --agent codex,cursor,claude-code
typescript:
name: TypeScript SDK and npm package
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk/typescript
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
- run: npm test
- run: npm run build
- name: Pack, install, and import the SDK
run: |
tarball="$RUNNER_TEMP/$(npm pack --silent --pack-destination "$RUNNER_TEMP")"
smoke_dir="$(mktemp -d)"
cd "$smoke_dir"
npm init -y >/dev/null
npm install "$tarball" >/dev/null
node --input-type=module -e 'import { defineSkill } from "@operatorstack/yield"; if (typeof defineSkill !== "function") process.exit(1)'
python:
name: Python SDK
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- run: python -m unittest discover -s sdk/python -p 'test_*.py'
rust:
name: Rust SDK
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: sdk/rust
- run: cargo test --manifest-path sdk/rust/Cargo.toml
conformance:
name: Four-language conformance
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache: true
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: |
sdk/rust
internal/conformance/testdata/skill-rs
- run: go vet ./...
- run: go test ./...
examples:
name: Example workflows and evaluations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache: true
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "24"
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: |
sdk/rust
examples/data-migration
examples/library/rust
- run: npm ci --ignore-scripts
- name: Rerun first-party evaluations
working-directory: evals
run: |
npm ci
npm test
- name: Validate semantic conversion receipt when required
working-directory: evals
env:
EVAL_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
EVAL_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: npm run test:conversion
- name: Run every example fixture
run: |
base_tag="$(git tag --merged HEAD --list 'v[0-9]*' --sort=-v:refname | head -n1)"
test -n "$base_tag"
pending_changesets="$(git diff --name-only --diff-filter=A "$base_tag"..HEAD -- '.changeset/*.md')"
if [[ -n "$pending_changesets" ]]; then
plan="$RUNNER_TEMP/example-release-plan.env"
node scripts/release-plan.mjs --bump auto --output "$plan" --notes "$RUNNER_TEMP/example-release-notes.md"
. "$plan"
else
version="${base_tag#v}"
fi
go build -ldflags "-X main.version=$version" -o "$RUNNER_TEMP/yskill" ./cmd/yskill
"$RUNNER_TEMP/yskill" test examples/investigate
"$RUNNER_TEMP/yskill" test examples/release-checklist
"$RUNNER_TEMP/yskill" test examples/env-doctor
"$RUNNER_TEMP/yskill" test examples/data-migration
YSKILL="$RUNNER_TEMP/yskill" "$RUNNER_TEMP/yskill" test examples/convert-skill
YSKILL="$RUNNER_TEMP/yskill" bash ./examples/library/test-all.sh
validate:
name: Release authority and full validation
if: ${{ always() }}
needs: [format, go, release, selfhost, typescript, python, rust, conformance, examples]
runs-on: ubuntu-latest
steps:
- name: Require every validation job
env:
RESULTS: ${{ toJSON(needs) }}
run: |
node -e '
const results = JSON.parse(process.env.RESULTS);
const failed = Object.entries(results).filter(([, value]) => value.result !== "success");
if (failed.length) {
console.error(failed.map(([name, value]) => `${name}: ${value.result}`).join("\n"));
process.exit(1);
}
'