{"id":21303073,"url":"https://github.com/bzon/monobuild","last_synced_at":"2025-03-15T18:45:53.049Z","repository":{"id":141932952,"uuid":"213095306","full_name":"bzon/monobuild","owner":"bzon","description":null,"archived":false,"fork":false,"pushed_at":"2019-10-13T14:29:44.000Z","size":7,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-22T08:28:14.130Z","etag":null,"topics":["continuous-integration","devops","go","monorepos"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bzon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-06T01:48:11.000Z","updated_at":"2019-10-27T11:18:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"83855e55-342d-406d-b638-1f368c45c494","html_url":"https://github.com/bzon/monobuild","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bzon%2Fmonobuild","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bzon%2Fmonobuild/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bzon%2Fmonobuild/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bzon%2Fmonobuild/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bzon","download_url":"https://codeload.github.com/bzon/monobuild/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243776693,"owners_count":20346353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuous-integration","devops","go","monorepos"],"created_at":"2024-11-21T15:58:49.959Z","updated_at":"2025-03-15T18:45:53.039Z","avatar_url":"https://github.com/bzon.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# monobuild [work in progress]\n\n*monobuild* or *mb* is a build tool for monorepos.\n\nA monorepo is a single repository that has multiple projects which may be maintained by different teams or people.\n\nIn the context of a Go-only monorepo, the following directory structure will make sense.\n\n```txt\ncmd\n  /server/\n  /worker/\n  /cli/\npkg\n  /api/\n  /db/\n  /utils/\n```\n\nWhat monorepo tools usually solve is to make builds faster by not building the sources that were not changed.\n\n## CICD problem with monorepo\n\nIn Go, it may not be a problem because binaries are built fast. \nThe problem is in the context of CICD deployment. \nIn CICD, every build, e.g. docker images, may trigger a deployment. \nAt scale, this means that if a project has 10 services, these 10 services will be changed. \nIf those 10 services has a total of 1000 replicas in production, you will have a massive deployment roll out.\n\n## Existing tools\n\nEvery team may have a different way to solve this problem.\n\n### [**Bazel**](https://bazel.build/) and [**Buck**](https://buck.build/)\n\nThese are tools made to build multiple languages in a monorepo.\n\nIf your team's monorepo is composed of multiple languages, then Bazel or Buck may make sense.\n\nThe only problem with using these tools is complexity. You are opting in to something that takes a significant time to learn.\n\n### **Bash scripts**\n\nA hacky and highly customized way to build a monorepo but maintenance cost a highly likely to be big.\n\n### **CI plugins**\n\nThis is good if it already solves your problem. The only problem is your build logic highly coupled with the CI provider.\n\n## Goals\n\nmonobuild goal is to standardised the build process for a specific language (currently just Go) and replace the use of highly complex bash scripts.\n\n## Definitions\n\n*Targets* - the target binaries to build. In Go, these are usually placed in the `./cmd/` directory.\n\n```yaml\ntargets:\n  - path: ./cmd/server\n  - path: ./cmd/worker\n  - path: ./cmd/cli-client\n```\n\n**Build triggers**\n\n*Target Dependency* - binaries have dependencies and we only want to build these binaries if their dependencies were changed.\nIn Go, these dependencies are typically Go files in `./pkg/`, `./vendor/` or `./internal/` directory.\n\n```yaml\ndep_source_dirs:\n  - ./pkg\n  - ./vendor\n  - ./internal\n```\n\n*Watch pattern (glob)* - Changes to these files will trigger a build for a specific target.\n\nGlobal level.\n\n```yaml\nwatch_pattern:\n  - ./** # will build all the targets if any files were changed in the root directory.\n```\n\nTarget level.\n\n```yaml\ntarget:\n  path: ./cmd/server\n  watch_pattern:\n  - cmd/worker/** # will build the ./cmd/server/main.go if any files from ./cmd/server/ were changed.\n```\n\n## How it works\n\nmonobuild only builds a target binary if:\n\n* Any files from the target binary directory has changed.\n* Any dependencies that the target binary uses has changed.\n* Any of the watched files has changed.\n\nThe list of changed files are extracted using `git diff --name-only [provided commit-range]`.\n\nThe list of dependencies \n\n### Go example\n\nTake this example of a **Go** monorepo structure.\n\n```txt\n├── bin # outputs\n│   ├── server\n│   └── worker\n├── cmd # targets\n│   ├── server\n│   │   ├── Dockerfile\n│   │   └── Makefile\n│   └── worker\n│       ├── Dockerfile\n│       └── Makefile\n├── vendor # packages\n│   └── foo \n└── pkg # packages\n    └── bar \n|__ monobuild.yaml\n```\n\nExample configuration file.\n\n```yaml\ndep_source_dirs:\n  - pkg\n  - internal\n  - vendor\ntargets:\n  - path: cmd/server\n    watch_pattern:\n    - monobuild.yaml\n    build_command:\n      dir: ./\n      command: make\n      args:\n        - -f\n        - cmd/server/Makefile\n        - build\n  - path: cmd/worker\n    watch_pattern:\n    - monobuild.yaml\n    build_command:\n      dir: ./\n      command: make\n      args:\n        - -f\n        - cmd/worker/Makefile\n        - build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbzon%2Fmonobuild","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbzon%2Fmonobuild","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbzon%2Fmonobuild/lists"}