Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Continuous Integration for the go-sdk.
#
# Runs build, vet, format check and tests, plus a cross-compile matrix across
# every OS/arch consumers ship on. The cross-compile job exists specifically to
# catch platform-portability regressions (e.g. Unix-only syscalls) at the
# source, before they reach downstream binaries.
#
# Scope matches the Makefile's PACKAGES (library packages only). The examples/
# tree is excluded because some examples depend on generated, gitignored files
# (e.g. portable-embedded-agent/secrets_gen.go).
name: CI

on:
push:
branches:
- main
- next
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
pull_request:
branches:
- main
- next
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'

permissions:
contents: read

env:
PACKAGES: ./sdk/... ./agent/... ./types/... ./internal/...

jobs:
check:
name: Build, Vet & Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache: true

- name: Vet
run: make vet

- name: Format check
run: make fmt-check

- name: Test
run: make test

- name: Build
run: go build ${{ env.PACKAGES }}

cross-compile:
name: Cross-compile (${{ matrix.goos }}/${{ matrix.goarch }})
runs-on: ubuntu-latest
needs: check
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
- goos: windows
goarch: amd64

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache: true

- name: Cross-compile
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: '0'
run: go build ${{ env.PACKAGES }}
33 changes: 33 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Release workflow for the go-sdk.
#
# go-sdk is a library, not a binary — for a Go module the git tag *is* the
# release (consumers fetch source via `go get`). This workflow therefore does
# not build or publish artifacts; it only creates a GitHub Release with
# auto-generated notes for the tag created by tag-release.yml.
#
# Triggered by tag-release.yml (workflow_dispatch at the new tag) or by a
# manually pushed `v*` tag.
name: Release

on:
push:
tags:
- 'v*'
workflow_dispatch:

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
65 changes: 65 additions & 0 deletions .github/workflows/tag-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Auto-tag when merging to main
#
# Reads the version from the VERSION file and, if the matching tag does not
# already exist, creates and pushes it. For a Go module the tag *is* the
# release, so this is what makes `go get @latest` / pinned versions resolve.
name: Tag Release

on:
push:
branches:
- main

jobs:
tag:
runs-on: ubuntu-latest
permissions:
contents: write
actions: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get version from VERSION file
id: version
run: |
if [ -f VERSION ]; then
VERSION=$(cat VERSION)
else
VERSION="0.0.0"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

- name: Check if tag exists
id: check_tag
run: |
if git rev-parse "v${{ steps.version.outputs.version }}" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Tag v${{ steps.version.outputs.version }} already exists"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "Tag v${{ steps.version.outputs.version }} does not exist"
fi

- name: Create and push tag
if: steps.check_tag.outputs.exists == 'false'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}"
git push origin "v${{ steps.version.outputs.version }}"

- name: Trigger release workflow
if: steps.check_tag.outputs.exists == 'false'
uses: actions/github-script@v7
with:
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'release.yml',
ref: 'v${{ steps.version.outputs.version }}'
})
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,25 @@ if err != nil {

- Go 1.21 or later

## Releasing

Versions are published as Git tags — for a Go module, the tag _is_ the release.
The version is driven by the [`VERSION`](VERSION) file:

1. Bump `VERSION` (semver, no `v` prefix — e.g. `0.2.0`) in a pull request.
2. Merge to `main`. The `Tag Release` workflow reads `VERSION` and, if the
matching `vX.Y.Z` tag does not yet exist, creates and pushes it, then
triggers the `Release` workflow to publish GitHub release notes.

Consumers then pin the new version:

```bash
go get github.com/chatbotkit/go-sdk@v0.2.0
```

While the API is still evolving the module stays on `v0.x` (minor versions may
introduce breaking changes); it will move to `v1.0.0` once the API is stable.

## License

See [LICENSE](LICENSE) for details.
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
Loading