minio/minio
Development workflow
A typical inner loop for a MinIO contributor.
Set up
git clone https://github.com/minio/minio
cd minio
git remote add upstream https://github.com/minio/minio
go install ./...go install ./... will fetch every dependency listed in go.mod (Go 1.24+ required) and produce a minio binary in $GOPATH/bin. Use make build to put it in the repo root with version-stamped LDFLAGS instead.
Branch
git checkout -b my-change upstream/masterThe project does not use long-lived feature branches. Every change is a fork-branch → PR → squash-merge to master.
Make changes
Three layers of work, each with its own etiquette:
Touching cmd/
Most server logic lives here. Conventions:
- HTTP handler signatures match
func (h objectAPIHandlers) MyVerbHandler(w http.ResponseWriter, r *http.Request). Look at neighbours in the same file for response writing helpers (writeSuccessResponseXML,writeErrorResponse,writeErrorResponseHeadersOnly). - New error codes go into
cmd/api-errors.goand the matching string table is regenerated viago generate. - Handlers acquire and release locks with
objectAPI.NewNSLock(...)fromcmd/namespace-lock.go. Holding a lock across a long network call is a known foot-gun.
Touching internal/
internal/ is for reusable, dependency-light modules. Anything you put there must compile without pulling in cmd/.
- New configurable settings live in
internal/config/<area>/. Each area registers itsHelpKVSandConfigtypes withinternal/config/config.go. - New event/notification targets go into
internal/event/target/and follow the existingSave/Send/Closeinterface. - New KMS providers go into
internal/kms/(the active integrations are KES viaaead.dev/mtlsand the local-key fallback).
Touching tests and docs
- Unit test files sit next to the file they test (
foo.go→foo_test.go). - Integration scripts live in
docs/<feature>/and are referenced fromMakefile. They run realminiobinaries and usemc.
Lint, format, generate
Before pushing:
make verifiersThis runs:
go generate ./...and fails if any_gen.godiffers.go mod tidyand fails ifgo.sumdiffers.golangci-lint run --build-tags kqueue --timeout=10m --config ./.golangci.yml.typos ./if thetyposbinary is on PATH (.typos.tomlcontrols allowlists).
If _gen.go files are dirty after go generate, commit them. They are produced by github.com/tinylib/msgp and golang.org/x/tools/cmd/stringer (both declared in the tool block of go.mod).
Test
make test # unit tests
make test-race # race-instrumented unit tests
make test-replication
make verify-healingSee Testing for what each of those does and which scripts they call.
Build
make build # ./minio
make install # $GOPATH/bin/minio
make install-race # race-instrumented binary in $GOPATH/bin/minioFor multi-arch:
env GOOS=linux GOARCH=arm64 go buildCommit
git add -A
git commit -m "concise subject line
Longer explanation of why the change was needed and what it
does. Wrap at 72 chars. Reference the related issue if there is one."Squash multiple WIP commits with git rebase -i before pushing.
Push and PR
git push origin my-changeOpen the PR on GitHub against minio/minio:master. The .github/workflows/ pipelines run verifiers, build, and the integration suites. Merges happen by squash.
After merge
- The PR title becomes the squash commit subject. The team re-uses commit subjects in release notes; aim for "Add X", "Fix Y", "Refactor Z" style.
- Releases are cut by tag. The release machinery is in
Makefile(hotfix,hotfix-push,releasetargets) andbuildscripts/gen-ldflags.go.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.