Guide Yield release decisions (#65) #151
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| ' |