ci: add Duo agent environment configuration

Description

Add an agent-config.yml to configure the CI/CD execution environment for GitLab Duo coding agent flows.

Why

When Duo Developer is triggered on an issue in this project, the agent runs in a default Docker environment that lacks the Go toolchain and project-specific tooling. This means the agent cannot build, test, or lint code — it can only write files and commit them blindly.

This gap was observed in !3177 (merged), where the agent introduced an import ordering issue (gci lint error) that it could not detect on its own. A reviewer had to manually copy the CI lint output into an MR comment and ask the agent to fix it — a slow, manual feedback loop that this configuration eliminates.

This MR adds a project-specific agent-config.yml that gives the agent the same development environment a human contributor would set up by following CONTRIBUTING.md.

What this does

The configuration:

  1. Uses golang:1.26 as the base image — matching our CI (default: image: golang:${GO_VERSION}). Provides Go, git, and make out of the box.

  2. **Bootstraps the full toolchain with **mise — the project's standard tool version manager. mise install reads .tool-versions and installs at the exact pinned versions:

    • Go 1.26.1
    • golangci-lint 2.11.4 (includes gofumpt and goimports formatters)
    • shellcheck 0.11.0
    • markdownlint-cli2 0.22.0
    • vale 3.13.0
    • lychee 0.21.0
    • Node.js 23.11.0
    • lefthook 2.0.2
  3. Installs commitlint dependencies so conventional commit validation works.

  4. Pre-downloads Go modules (go mod download) so the agent doesn't hit the network mid-task.

  5. Activates lefthook git hooks — this is the key quality gate. The agent gets automatic validation on every commit and push:

    Hook stage Trigger Checks
    pre-commit git commit golangci-lint --fix (auto-formats code with gofumpt/goimports), shellcheck, markdownlint --fix, auto-regenerates docs if command files changed
    commit-msg git commit Conventional commit format validation via commitlint
    pre-push git push make build, golangci-lint (changed files vs main), make test-changed (tests on changed packages + reverse deps), verify generated docs/code are up to date, markdownlint, vale, lychee
  6. Caches Go modules and mise tool installations between flow runs, keyed on go.sum and .tool-versions so the cache invalidates when dependencies or tool versions change.

Testing

This was tested on a local GDK instance by:

  1. Pushing the CLI repo (with this config on main) to a GDK project
  2. Creating a test issue: "Add a glab mr stats subcommand that displays summary statistics for a merge request"
  3. Assigning Duo Developer to the issue

Results:

  • The setup script executed successfully
  • The agent wrote Go code, tests, and command registration
  • Lefthook pre-commit hooks fired: golangci-lint auto-fixed formatting, commitlint validated the commit message, docs regeneration check passed
  • The agent caught and fixed 3 lint issues during development (named returns, unchecked error, import ordering) — exactly the kind of feedback loop we want
  • make build, go test, make gen-docs all passed
  • The agent created a working MR with a proper conventional commit

How to test locally with GDK

Prerequisites: a running GDK with a runner configured using the Docker executor and the gitlab--duo tag.

# 1. Add your GDK as a remote (one-time setup)
git remote add gdk http://root:<YOUR_TOKEN>@gdk.test:3000/<namespace>/cli.git

# 2. Push the branch with agent-config.yml to GDK
#    (it must be merged to main on GDK for the config to take effect)
git push gdk add-duo-agent-config:main

# 3. Create a test issue on the GDK project — for example:
#    "Add a glab mr stats subcommand that displays summary statistics
#     for a merge request: number of commits, changed files, additions,
#     and deletions. Output should support both text and --output json
#     formats. Include unit tests following the cmdtest and gitlabtesting
#     patterns."

# 4. Trigger Duo Developer on the issue (assign or use the UI)

# 5. Observe the CI job logs for:
#    - mise installing all tools from .tool-versions
#    - lefthook hooks firing on commit (golangci-lint, commitlint)
#    - lefthook hooks firing on push (build, lint, test-changed)
#    - The agent being able to run: make build, make test, make lint
Edited by Thomas Schmidt

Merge request reports

Loading