Examples

Go SDKs with explicit build and release flow

A Go SDK contract that keeps build, lint, and release guidance obvious.

copynew usersbasicstable2026-05-30

Typical signals

  • container backend is explicit
  • Go module dependencies are explicit
  • release checks stay separate from release versioning
  • notes explain the command order for release work

Why it matters

  • it turns a repo pattern into something humans, CI, and agents can read the same way
  • it makes the next command obvious instead of implied by README drift
  • it keeps readiness, setup, and execution explainable in receipts and diagnostics

Example contract

This example treats the SDK as a product surface: the core loop stays short, and the release path is documented in the task notes.

ota.yamlyaml
version: 1project:  name: go-sdk  description: Go SDK with explicit release and changelog flow  type: librarymetadata:  team: sdk  owner: ota  repo_class: go-sdkruntimes:  go: '>=1.21'execution:  preferred: container  supported:    - native    - container  backends:    container:      image: ghcr.io/ota-run/go-sdk:latest      engines:        - docker        - podmantools:  go: '*'  golangci-lint:    version: "1.64.8"    acquisition:      provider: command      shell: sh      run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.8  docker: '*'tasks:  setup:    internal: true    description: Download Go module dependencies    notes: |      Use this first after cloning or when module dependencies change.    category: setup    run: go mod download    safe_for_agent: true  build:    description: Build the Go SDK    notes: |      Use this to confirm the Go package still builds cleanly.    category: build    command:      exe: go      args:        - build        - ./...    depends_on:      - setup    safe_for_agent: true  test:    description: Run the Go test suite    notes: |      Use this for the standard Go unit test pass.    category: test    command:      exe: go      args:        - test        - ./...    depends_on:      - setup    safe_for_agent: true  vet:    description: Run Go vet    notes: |      Use this for static analysis of suspicious Go code patterns.    category: test    run: go vet ./...    depends_on:      - setup    safe_for_agent: true  lint:    description: Run golangci-lint    notes: |      Use this for the full lint gate before merging changes.    category: test    command:      exe: golangci-lint      args:        - run        - ./...    depends_on:      - setup    requirements:      tools:        golangci-lint: "*"    safe_for_agent: true  release:check:    description: Run the release verification suite    notes: |      Use this as the release gate before tagging or pushing a release.      This task composes build, test, vet, and lint.      `ota run release:check`      Typical flow:        ota run release:check        ota run release:version --version x.y.z    category: release    depends_on:      - build      - test      - vet      - lint    script: ":"    safe_for_agent: true  release:version:    description: Bump the SDK version and promote the changelog    notes: |      Use this when preparing a new release version.      `ota run release:version --version 0.2.1`      Run `ota run release:check` before this task.      This updates the SDKVersion constant in config.go and promotes the      Unreleased changelog entry into the new version section.      The task forwards `--version` into `OTA_INPUT_VERSION`.    category: release    depends_on:      - release:check    script: |      version="${OTA_INPUT_VERSION}"      if [ -z "$version" ]; then        echo "Usage: ota run release:version --version <x.y.z>" >&2        exit 1      fi       if ! printf '%s' "$version" | grep -Eq '^[0-9]+.[0-9]+.[0-9]+([.-][0-9A-Za-z.-]+)?(+[0-9A-Za-z.-]+)?$'; then        echo "Invalid semver version: $version" >&2        exit 1      fi       release_date="$(date -u +%F)"       perl -0pi -e 's/const SDKVersion = "[^"]+"/const SDKVersion = "'$version'"/' config.go      echo "Updated config.go SDKVersion to $version"       if grep -Eq '^## ['"$version"'] - ' CHANGELOG.md; then        echo "CHANGELOG.md already contains release $version"        exit 0      fi       if ! grep -Eq '^## [Unreleased]$' CHANGELOG.md; then        echo "CHANGELOG.md is missing the Unreleased heading" >&2        exit 1      fi       perl -0pi -e 's/^## [Unreleased] /## [Unreleased] ## ['"$version"'] - '"$release_date"' /m' CHANGELOG.md      echo "Updated CHANGELOG.md for $version"    inputs:      version:        description: New release version to apply to config.go        required: truechecks:  - name: container-engine    kind: precondition    severity: error    run: docker --version 

Task notes

Task notes stay close to the task they explain.

Use notes: when a task needs short operator guidance, not long prose.

Keep each note command-oriented and specific to the task that follows it.

For release tasks, put the sequence and the required input flag in the note itself.