Development process guidelines

Specifications sign-off from a Go developer

Specifications requiring changes of Go code need sign-off (thumbs up) from a Go developer

Initialize new repositories with Go and git base settings

  • .gitignore with a default ignored files from https://www.toptal.com/developers/gitignore
  • .golangci.yaml with contents copied from some other Go codebase and adjusted for the new repositories needs. Currently, best source for an up-to-date .golangci.yaml file is MSSQL plugin
  • README.md

New code must follow code style guidelines

When restructuring code (moving files or functions) the changes made are not considered "New Code", but changes will be caught by lint, so when doing restructuring changes you will likely need to fix lint issues in the moved code.

Changes done to a Zabbix dependency module, must be applied to all components that dependency

You make changes to plugin-support, you have to apply the new plugin-support to all components that use it.

Components with Zabbix dependency modules, must use a version of the dependency from a release branch

Since plugin-support does not have version tags, that Go module versioning could use, we have to make do with commit hashes. The commit hashes used in components must be from release branches, not development branches.

Merge dependencies first, retrieve and apply the merged dependencies commit hash, merge the component

The previous guideline rule defines the merge order requirement. Merge dependencies first, retrieve the commit hash from merge to release branch, apply the dependency commit hash to a component, and only then merge the component's dev branch into a release branch.

Changes to Agent2 and its support components and libraries must follow the common commit message format.

  • G - Agent 2 and its surrounding components (e.g. plugin-support and plugins (PostgreSQL, MongoDB, MSSQL))

    ...G...... [{ticket_id}] message
  • T - Zabbix integrations (Kafka Connector, SNMP Gateway)

    .........T [{ticket_id}] message

Don't prefix non-Agent2 commit messages with component

There are multiple Go code repositories separate of main Zabbix mono-repo. Since there is no need to separate changes made by component as it's done for Zabbix main mono-repo, commit messages for the following repositories should be in the format [Ticket-ID] message

Use N-1 version of Go

Zabbix supports two latest Go versions, so using lowest of the two ensures that we don't introduce changes that build on version N, but don't on version N-1.

Run go mod tidy before publishing changes

Merge can also introduce go.mod and go.sum conflicts (even if git does not consider them conflicts), that break build, hence run go mod tidy after merges.

Never use //nolint:all.

Any changes to lint config (.golangci.yaml file in the root of a codebase) must be approved by a Go developer

//nolint:xxx go directives are allowed

Lint will always have false positives and cases when the developer knows better. In review the nolint directives should be carefully examined. Confirming that nolint is actually necessary, and the logic cannot be rewritten to adhere to lint rules.

For non-Agent2 components lint must pass for the whole codebase

golangci-lint run must have exit code 0.

For Agent2 lint must pass for the changes made

golangci-lint run --new-from-rev=HEAD~N must have exit code 0 when run on the new commits.

Linter version on local env should match the version specified by config (a comment line)

Run gofmt before publishing changes

Ideally set up automatic formatting on save.

Suggested tooling

Additionally, the following tools can be used to reduce ambiguity even further and ease the development experience. (A really warm suggestion to use all of them.)

  • gofumpt - a stricter gofmt
  • golines - splits long lines
  • goimports - automatically imports used packages
  • gci - orders package imports deterministically
  • gotests - unit test generation tool (must have if you have to write unit tests)
  • golangci-lint - lint runner
  • cspell - spell checker, with config "language": "en_US"
  • gotestsum a better go test

Make sure everything works before publishing changes

To state the obvious - make sure the task is implemented and works.

From Go development process side of things make sure that:

  • changes build on linux and windows platforms
  • make sure that unit tests pass
  • make sure that lint passes
  • make sure that your changes are formatted
  • make sure that go.sum and go.mod are up-to-date

If any of the before mentioned checks fail with weird errors running go clean -cache might help.

Also, many Go code repositories might these checks defined as part of a make file, use that.

All changes to the Go codebase require approval from a Go developer to be merged.

Unit test your changes

  • New code must be unit tested.
  • Working on existing code unit test it.
  • Preserve existing test cases during updates or refactoring.
  • Add regression unit tests for fixed bugs if possible.
  • Strive for 100% coverage, but 90% is reasonable.
  • Follow Go Unit Test Style Guidelines.

Final decision on whether unit tests are required rests with the Go developer reviewer.