Thank you for your interest in contributing to the AxonFlow Go SDK! We welcome contributions from the community.
All contributions to this repository must be signed off under the Developer Certificate of Origin v1.1. The DCO is a per-commit affirmation that you wrote the code (or otherwise have the right to submit it) and are licensing it under the same license as the rest of this repository.
Add the sign-off automatically with -s (or --signoff) on every commit:
git commit -s -m "your commit message"This appends a trailer like:
Signed-off-by: Your Name <your.email@example.com>
The name and email must match git config user.name / git config user.email.
If you forgot -s on an existing commit, fix it with one of:
# most recent commit
git commit --amend --signoff --no-edit
# every commit on the current branch
git rebase --signoff origin/mainA DCO check runs automatically on every PR opened in the getaxonflow org. PRs with any unsigned commit will be blocked from merging until the missing sign-offs are added. No exceptions, including for maintainers.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/axonflow-sdk-go.git - Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes
- Run tests:
go test ./... - Commit your changes:
git commit -m "Add your feature" - Push to your fork:
git push origin feature/your-feature-name - Open a Pull Request
- Go 1.21 or higher
- Git
git clone https://github.com/getaxonflow/axonflow-sdk-go.git
cd axonflow-sdk-go
go mod download# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Run tests with verbose output
go test -v ./...When you add or rename an exported struct whose type name matches an
OpenAPI schema in the platform specs, a CI job diffs the JSON tags
against the spec and fails the PR on drift. This is enforced by
contract_wire_shape_test.go (opt-in via the AXONFLOW_OPENAPI_SPECS_DIR
env var).
Run locally, against the committed spec snapshot (see
testdata/openapi/README.md for what it holds and how it is derived):
AXONFLOW_OPENAPI_SPECS_DIR=$PWD/testdata/openapi \
go test -v -run "TestWireShape" .Without the env var, the tests skip cleanly — a plain go test ./...
doesn't need the specs.
If you legitimately need to update the acknowledged baseline (e.g. a drift entry was burned down, or a new acknowledged divergence was added), regenerate it with:
go run ./scripts/refresh_wire_shape_baseline testdata/openapiThe pinned commit comes from the snapshot's generated headers (see
testdata/openapi/README.md), so the command takes no --sha.
Never regenerate to silence a failure without understanding what drifted; that defeats the gate.
The wire-shape gate pins the OpenAPI spec revision via
openapi_specs_sha in the baseline so a given SDK commit always diffs
against the same spec. Changing that SHA in the same PR that changes
SDK structs can silently retarget the gate past drift it should have
caught, so the CI job enforces an extra guardrail: any PR that moves
openapi_specs_sha, or changes a file under testdata/openapi/, must
also carry the spec-pin-bump label, which
surfaces the bump for explicit review.
Recommended flow:
- Open a dedicated PR that regenerates the snapshot at the new
platform commit and the baseline from it (see
testdata/openapi/README.md), and nothing else. - Apply the
spec-pin-bumplabel. - Merge.
- Follow up with the SDK-side changes that the new spec enables.
If it's genuinely one change (platform + SDK shipping together), apply the label to the single PR — the label just signals the reviewer to scrutinise the SHA move.
Set up your environment variables:
export AXONFLOW_AGENT_URL="http://localhost:8080" # Local docker-compose default
export AXONFLOW_CLIENT_ID="your-client-id"
export AXONFLOW_CLIENT_SECRET="your-client-secret"Run examples:
# Basic example
go run examples/basic/main.go
# Connectors example
go run examples/connectors/main.go
# Planning example
go run examples/planning/main.go- Follow standard Go formatting:
go fmt ./... - Run linting:
go vet ./... - Keep functions focused and well-documented
- Use meaningful variable and function names
- Add comments for exported functions and types
- Keep PRs focused: One feature or fix per PR
- Update documentation: If you change the API, update README.md
- Add tests: All new features should include tests
- Pass CI checks: Ensure all tests pass before submitting
- Write clear commit messages: Describe what and why, not how
Add feature: brief description
Detailed explanation of the changes and why they were made.
Any breaking changes should be clearly noted.
Have an idea for a new feature? We'd love to hear it!
- Check existing issues to avoid duplicates
- Open a new issue with the "Feature Request" label
- Describe the feature and its use case
- Discuss implementation approach
Found a bug? Help us fix it!
- Check existing issues to avoid duplicates
- Open a new issue with the "Bug" label
- Include:
- Go version
- Operating system
- Steps to reproduce
- Expected behavior
- Actual behavior
- Error messages or logs
We use Go's built-in testing framework. When adding new features:
- Add unit tests for new functions
- Add integration tests for API interactions
- Ensure test coverage remains high
- Mock external dependencies when appropriate
Example test structure:
func TestClientProxyLLMCall(t *testing.T) {
client := NewClientSimple("https://example.com", "id", "secret")
resp, err := client.ProxyLLMCall("token", "query", "chat", nil)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if resp == nil {
t.Error("Expected response, got nil")
}
}- Update README.md for user-facing changes
- Add GoDoc comments for all exported functions and types
- Include usage examples in comments when helpful
- Keep documentation clear and concise
- All PRs require at least one approval
- Maintainers will review your PR within 3-5 business days
- Address feedback and update your PR
- Once approved, a maintainer will merge your PR
The wire-shape contract gate uses a baseline file (testdata/wire_shape_baseline.json) to grandfather pre-existing drift findings — the gate fails on any new drift but tolerates the listed entries. The baseline exists to land the gate without a giant cleanup PR; it is not intended to be permanent.
When your PR touches a type listed in the baseline, do one of:
- Burn it down. Realign the struct with the OpenAPI spec in this PR, regenerate the baseline (
go run ./scripts/refresh_wire_shape_baseline testdata/openapi), and note "burndown:<entry>" in the PR description. - Justify it. If the drift can't be resolved in this PR (different scope, blocked on a platform spec change, etc.), say so in the PR description in one line.
CI does not block PRs that touch a baselined type without addressing it, but reviewers will ask the burndown-or-justify question.
By contributing to AxonFlow Go SDK, you agree that your contributions will be licensed under the MIT License.
If you have questions about contributing, feel free to:
- Open a discussion on GitHub
- Email us at hello@getaxonflow.com
- Check our documentation at https://docs.getaxonflow.com
Thank you for contributing to AxonFlow!