Graph
Terrabuild is based on DAG (Direct Acyclic Graph) where nodes are tasks to complete to reach a given goal.
This graph is based on projects and configurations of your workspace. Nodes of this graph have relationship with other nodes: they are the discovered or specified dependencies of the projects. Project configuration is specified using an HCL-like syntax.
Building this graph is important since this enables Terrabuild to perform important optimizations:
- do not build what has not changed
- use pre-built binaries
- narrow build scope
Example workspace
Imagine following projects and dependencies as follow. Projects are managed individually, and each have a dedicated PROJECT. Projects have dependencies - inferred most of the time.
Example taken from Terrabuild Playground. This is a sample workspace you can use to start with Terrabuild.
flowchart LR classDef default fill:moccasin,stroke:black classDef project fill:gainsboro,stroke:black,rx:10,ry:10 classDef build fill:palegreen,stroke:black,rx:20,ry:20 classDef publish fill:skyblue,stroke:black,rx:20,ry:20 classDef target fill:white,stroke-width:2px,stroke-dasharray: 5 2 subgraph A[".net WebApi"] subgraph targetBuildA["target build"] direction LR buildA(["@dotnet build"]) end subgraph targetBuildA["target build"] direction LR buildA(["@dotnet build"]) end subgraph targetPublishA["target dist"] direction LR dockerA(["@docker build"]) --> publishA(["@dotnet publish"]) end class targetBuildA build class targetPublishA publish end subgraph B["Vue.js WebApp"] subgraph targetBuildB["target build"] direction LR publishB(["@npm build"]) end subgraph targetPublishB["target dist"] direction LR dockerB(["@docker build"]) end class targetBuildB build class targetPublishB publish end subgraph C[".net Library"] subgraph targetBuildC["target build"] direction LR buildC(["@dotnet build"]) end class targetBuildC build end subgraph D["Typescript Library"] subgraph targetBuildD["target build"] direction LR buildD(["@npm build"]) end class targetBuildD build end publish([deploy]) targetBuildB --> targetBuildD targetBuildA --> targetBuildC targetPublishA --> targetBuildA publish -.-> targetPublishA targetPublishB --> targetBuildB publish -.-> targetPublishB class A,B,C,D project class publish target
Build graph is as follow:
flowchart LR classDef forced stroke:red,stroke-width:3px classDef required stroke:orange,stroke-width:3px classDef selected stroke:black,stroke-width:3px 942179365051C1A33DCF747C64D41786C8982DD5C9B7EB7D8792D5AB26BC93EE([build src/apps/webapi]) 2472A7D7AFE84797E8835F7F8AAA9671A230BC0391CD60D47D68F0982D660F4D([build src/libs/cslib]) 942179365051C1A33DCF747C64D41786C8982DD5C9B7EB7D8792D5AB26BC93EE --> 2472A7D7AFE84797E8835F7F8AAA9671A230BC0391CD60D47D68F0982D660F4D class 942179365051C1A33DCF747C64D41786C8982DD5C9B7EB7D8792D5AB26BC93EE required class 2472A7D7AFE84797E8835F7F8AAA9671A230BC0391CD60D47D68F0982D660F4D required 6AE17A5B59E873CC19549EC37FF0E70529F5ACF9199EF788A57AA36D515D5305([plan src/deploy]) class 6AE17A5B59E873CC19549EC37FF0E70529F5ACF9199EF788A57AA36D515D5305 required A4784F53304358C5B2A731D8ADEA338F8DE2217105C7A0B1D76E9CE3536D946F([build src/apps/webapp]) 09B7D90F73A18A551759DF0B8F900113268C2015C4B23E930DC1EF5427F55EA4([build src/libs/tslib]) A4784F53304358C5B2A731D8ADEA338F8DE2217105C7A0B1D76E9CE3536D946F --> 09B7D90F73A18A551759DF0B8F900113268C2015C4B23E930DC1EF5427F55EA4 class A4784F53304358C5B2A731D8ADEA338F8DE2217105C7A0B1D76E9CE3536D946F required class 09B7D90F73A18A551759DF0B8F900113268C2015C4B23E930DC1EF5427F55EA4 required C84DDA0307CE672A87A67571C61AF0A56E74CC8C6AB291EB1AAF863E0EAE4905([dist src/apps/webapi]) C84DDA0307CE672A87A67571C61AF0A56E74CC8C6AB291EB1AAF863E0EAE4905 --> 942179365051C1A33DCF747C64D41786C8982DD5C9B7EB7D8792D5AB26BC93EE class C84DDA0307CE672A87A67571C61AF0A56E74CC8C6AB291EB1AAF863E0EAE4905 required 20A918F5A24BDC971D2453B59EB07784463ABFFE026049F1A1BB5C0BE1F06576([deploy src/deploy]) 20A918F5A24BDC971D2453B59EB07784463ABFFE026049F1A1BB5C0BE1F06576 --> C84DDA0307CE672A87A67571C61AF0A56E74CC8C6AB291EB1AAF863E0EAE4905 20A918F5A24BDC971D2453B59EB07784463ABFFE026049F1A1BB5C0BE1F06576 --> F7DB4DD0555F1851A6EDF90789A946B7D9385F94186559AC6124CEC556EA1B44 20A918F5A24BDC971D2453B59EB07784463ABFFE026049F1A1BB5C0BE1F06576 --> 6AE17A5B59E873CC19549EC37FF0E70529F5ACF9199EF788A57AA36D515D5305 class 20A918F5A24BDC971D2453B59EB07784463ABFFE026049F1A1BB5C0BE1F06576 required F7DB4DD0555F1851A6EDF90789A946B7D9385F94186559AC6124CEC556EA1B44([dist src/apps/webapp]) F7DB4DD0555F1851A6EDF90789A946B7D9385F94186559AC6124CEC556EA1B44 --> A4784F53304358C5B2A731D8ADEA338F8DE2217105C7A0B1D76E9CE3536D946F class F7DB4DD0555F1851A6EDF90789A946B7D9385F94186559AC6124CEC556EA1B44 required
If a project needs to be rebuild (either one of its dependency changed or files of the project changed), its dependencies are restored on demand and then project can be built. Note that if this project is a dependency of another project, the latter will be rebuilt automatically.
Corrolary: it’s possible a branch does not need to be rebuilt if nothing has changed. Even no artifacts will be downloaded at all. You will have really fast builds in your workspace since usually, few projects need to be rebuilt.