Skip to content
Open
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
56 changes: 55 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,87 @@ concurrency:
cancel-in-progress: true

jobs:
discover:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: set-modules
run: |
MODULES=$(find . -not -path '*/\.git/*' -name go.mod -exec dirname {} \; | sort | jq -R -s -c 'split("\n")[:-1]')
echo "modules=$MODULES" >> $GITHUB_OUTPUT

test:
needs: discover
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module: ${{ fromJson(needs.discover.outputs.modules) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup
uses: ./.github/actions/setup

- name: Tidy
- name: Initialize workspace
run: go work init && go work use -r .

- name: Tidy Check
working-directory: ${{ matrix.module }}
run: go mod tidy -diff

- name: Build
working-directory: ${{ matrix.module }}
run: go build -mod=readonly -v ./...

- name: Test
working-directory: ${{ matrix.module }}
run: go test -race -mod=readonly -v -count=1 -shuffle=on ./...

lint:
needs: discover
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module: ${{ fromJson(needs.discover.outputs.modules) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup
uses: ./.github/actions/setup

- name: Initialize workspace
run: go work init && go work use -r .

- name: Lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
working-directory: ${{ matrix.module }}
install-mode: goinstall
version: 5256574b81bcedfbcae9099f745f6aee9335da10 # v2.3.1

guardrail:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup
uses: ./.github/actions/setup

- name: Check root go.mod against internal modules
run: |
ROOT_REQS=$(go mod edit -json | jq -r '.Require // [] | .[] | .Path')

FAIL=0
while IFS= read -r -d '' dir; do
MOD_PATH=$(cd "$dir" && go mod edit -json | jq -r '.Module.Path')
if [ -n "$MOD_PATH" ] && echo "$ROOT_REQS" | grep -F -x -q "$MOD_PATH"; then
echo "ERROR: Root go.mod requires internal submodule $MOD_PATH"
FAIL=1
fi
done < <(find . -mindepth 2 -not -path '*/\.git/*' -name go.mod -printf '%h\0')

exit $FAIL
26 changes: 25 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,42 @@ on:
workflow_dispatch:

jobs:
discover:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: set-modules
run: |
MODULES=$(find . -not -path '*/\.git/*' -name go.mod -exec dirname {} \; | sort | jq -R -s -c 'split("\n")[:-1]')
echo "modules=$MODULES" >> $GITHUB_OUTPUT

test:
needs: discover
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module: ${{ fromJson(needs.discover.outputs.modules) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup
uses: ./.github/actions/setup


- name: Nightly Test
working-directory: ${{ matrix.module }}
run: go test -race -mod=readonly -v -count=1 -shuffle=on ./...

vulncheck:
needs: discover
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module: ${{ fromJson(needs.discover.outputs.modules) }}
steps:
- name: Run govulncheck
# NOTE: pinned to master HEAD instead of a tag. The latest release (v1.0.4)
Expand All @@ -28,5 +51,6 @@ jobs:
# TODO: re-pin to a tagged release once upstream tags one past v1.0.4.
uses: golang/govulncheck-action@31f7c5463448f83528bd771c2d978d940080c9fd # master, post-v1.0.4 (Node 24)
with:
go-version-file: go.mod
go-version-file: ${{ matrix.module }}/go.mod
work-dir: ${{ matrix.module }}
repo-checkout: true
24 changes: 24 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Run from the repo root. These match what CI enforces (CI also passes `-v`):
- Tidy check: `go mod tidy -diff` (must print nothing)
- Format: `golangci-lint fmt` (applies gofumpt + goimports per config)

**Local Development**: Contributors should use `go work init && go work use -r .` to set up their local workspaces.

## Definition of done

A change is complete only when all of these pass locally:
Expand Down Expand Up @@ -104,6 +106,28 @@ See `examples/quickstart` for a full runnable program.
- **Add cross-cutting behavior:** register a `plugin.New(plugin.Config{...})`
hook (`Before*`/`After*` for run/agent/model/tool) instead of editing the loop.

## Multi-Module Development

**Policy**: New integrations with heavy or optional dependencies must be created as separate Go modules.

**Steps to Add a New Module (e.g., `plugin/myplugin`)**:
1. Navigate into the directory: `cd <module_directory_path>`
2. Initialize the module: `go mod init google.golang.org/adk/<module_directory_path>`
3. Add your Go code, dependencies, and tests.
4. Tidy the module: `go mod tidy`
5. Return to the repo root.
6. Tidy the root module: `go mod tidy`
7. Verify everything builds and tests from the root: `go build work && go test work`. The CI will automatically pick up the new module on the PR.

**Release Tagging**:
- **Core Module**: Tags remain `vX.Y.Z` (e.g., `v2.1.0`).
- **Submodules**: Tags are prefixed with the full module path directory, e.g., `plugin/agentanalytics/v0.1.0`. This is the standard Go way to version modules not at the repo root.
- **go get / go install**: Consumers will use:
- `go get google.golang.org/adk/v2@v2.1.0`
- `go get google.golang.org/adk/plugin/agentanalytics@v0.1.0`
- **Version Coupling**: Each submodule's `go.mod` will specify the minimum version of `google.golang.org/adk/v2` it depends on. Submodules can be released independently of the core module and each other.
- **go.work Impact**: `go.work` is for local development only and does not affect how modules are versioned, tagged, or fetched by consumers.

## Testing

- Tests run **offline by default**: LLM HTTP traffic is replayed from
Expand Down
25 changes: 25 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ We'd love to accept your patches and contributions to this project.

- [How to contribute](#how-to-contribute)
- [Branches](#branches)
- [Multi-Module Development](#multi-module-development)
- [Before you begin](#before-you-begin)
- [Sign our Contributor License Agreement](#sign-our-contributor-license-agreement)
- [Review our community guidelines](#review-our-community-guidelines)
Expand Down Expand Up @@ -43,6 +44,30 @@ To work on a 1.x fix, base your branch on `v1`:
git switch -c my-fix origin/v1
```

## Multi-Module Development

**Policy**: New integrations with heavy or optional dependencies must be created as separate Go modules.

**Local Development**: Contributors should use `go work init && go work use -r .` to set up their local workspaces.

**Steps to Add a New Module (e.g., `plugin/myplugin`)**:
1. Navigate into the directory: `cd <module_directory_path>`
2. Initialize the module: `go mod init google.golang.org/adk/<module_directory_path>`
3. Add your Go code, dependencies, and tests.
4. Tidy the module: `go mod tidy`
5. Return to the repo root.
6. Tidy the root module: `go mod tidy`
7. Verify everything builds and tests from the root: `go build work && go test work`. The CI will automatically pick up the new module on the PR.

**Release Tagging**:
- **Core Module**: Tags remain `vX.Y.Z` (e.g., `v2.1.0`).
- **Submodules**: Tags are prefixed with the full module path directory, e.g., `plugin/agentanalytics/v0.1.0`. This is the standard Go way to version modules not at the repo root.
- **go get / go install**: Consumers will use:
- `go get google.golang.org/adk/v2@v2.1.0`
- `go get google.golang.org/adk/plugin/agentanalytics@v0.1.0`
- **Version Coupling**: Each submodule's `go.mod` will specify the minimum version of `google.golang.org/adk/v2` it depends on. Submodules can be released independently of the core module and each other.
- **go.work Impact**: `go.work` is for local development only and does not affect how modules are versioned, tagged, or fetched by consumers.

## Before you begin

### Sign our Contributor License Agreement
Expand Down
Loading