github.com/tilt-dev/tilt@v0.36.0/CONTRIBUTING.md (about) 1 # Hacking on Tilt 2 3 So you want to make a change to `tilt`! 4 5 ## Guidelines 6 7 We welcome contributions, either as bug reports, feature requests, or pull requests. 8 9 We want everyone to feel at home in this repo and community! 10 Please read our [**Code of Conduct**](https://docs.tilt.dev/code_of_conduct.html) for some rules that govern everyone's participation. 11 12 Most of this page describes how to get set up making & testing changes. 13 See a [YouTube walkthrough](https://youtu.be/oGC5O-BCBhc) showing some of the steps below, for macOS. 14 15 Small PRs are better than large ones. 16 If you have an idea for a major feature, please file an issue first. 17 18 ## Clone 19 To check out Tilt for the first time, run: 20 21 ``` 22 git clone https://github.com/tilt-dev/tilt.git 23 ``` 24 25 ## Build 26 ### Prerequisites 27 If you just want to build Tilt: 28 29 - **[make](https://www.gnu.org/software/make/)** 30 - **[go](https://golang.org/dl/)** (see `go.mod` for supported version) 31 - **C/C++ toolchain** (for CGO dependencies) 32 - **[golangci-lint](https://github.com/golangci/golangci-lint)** (to run lint) 33 34 To use the local Webpack server for UI (default for locally compiled versions of Tilt): 35 - **[Node.js](https://nodejs.org/en/download/)** (LTS - see `.engines.node` in `web/package.json`) 36 - **[yarn](https://yarnpkg.com/lang/en/docs/install/)** 37 38 ### Build & Install From Source 39 To install `tilt` on PATH, run: 40 41 ``` 42 make build-js 43 make install 44 ``` 45 46 > Running the `build-js` task is currently optional but _highly_ recommended. 47 > If available, the build will embed the frontend assets in the `tilt` binary, 48 > which allows Tilt to work offline. Otherwise, assets will be served at runtime 49 > from a remote server. 50 51 This will install the new `tilt` binary in `$GOPATH/bin` - typically `$HOME/go/bin`. 52 You can verify this is the binary you just built with: 53 ``` 54 "$(go env GOPATH)/bin/tilt" version 55 ``` 56 57 The build date should match the current date. 58 Be aware that you might already have a `tilt` binary in your $PATH, so running `tilt` without specifying exactly which `tilt` binary you want might have you running the wrong binary. 59 60 ### Running 61 To start using Tilt, run `tilt up` in any project with a `Tiltfile` -- i.e., NOT the root of the Tilt source code. 62 There are plenty of toy projects to play with in the [integration](https://github.com/tilt-dev/tilt/tree/master/integration) directory 63 (see e.g. `./integration/oneup`), or check out one of these sample repos to get started: 64 - [ABC123](https://github.com/tilt-dev/abc123): Go/Python/JavaScript microservices generating random letters and numbers 65 - [Servantes](https://github.com/tilt-dev/servantes): a-little-bit-of-everything sample app with multiple microservices in different languages, showcasing many different Tilt behaviors 66 - [Frontend Demo](https://github.com/tilt-dev/tilt-frontend-demo): Tilt + ReactJS 67 - [Live Update Examples](https://github.com/tilt-dev/live_update): contains Go and Python examples of Tilt's [Live Update](https://docs.tilt.dev/live_update_tutorial.html) functionality 68 - [Sidecar Example](https://github.com/tilt-dev/sidecar_example): simple Python app and home-rolled logging sidecar 69 70 ## Test 71 ### Prerequisites 72 If you want to run the tests: 73 74 - **[docker](https://docs.docker.com/install/)** - Many of the `tilt` build steps do work inside of containers 75 so that you don't need to install extra toolchains locally (e.g., the protobuf compiler). 76 - **[kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)** 77 - **[kustomize 2.0 or higher](https://github.com/kubernetes-sigs/kustomize)**: `go get -u sigs.k8s.io/kustomize` 78 - **[helm](https://docs.helm.sh/using_helm/#installing-helm)** 79 - **[docker compose](https://docs.docker.com/compose/install/)**: NOTE: this doesn't need to be installed separately from Docker on macOS 80 - **[jq](https://stedolan.github.io/jq/download/)** 81 82 ### Running Test Suite (Fast) 83 To run the fast test suite, run: 84 85 ``` 86 make shorttest 87 ``` 88 89 ### Running Test Suite (Slow) 90 To run the slow test suite that interacts with Docker and builds real images, run: 91 92 ``` 93 make test 94 ``` 95 96 ### Running Integration Tests 97 If you want to run an integration test suite that deploys servers to Kubernetes and 98 verifies them, run: 99 100 ``` 101 make integration 102 ``` 103 104 ### Optional/Other 105 106 Other development commands: 107 108 - **[goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports?tab=doc)**: `go install golang.org/x/tools/cmd/goimports@latest` (to sort imports) 109 - Run manually with `make goimports` 110 - Run automatically with IDE 111 - See goimports docs for IDE specific configuration instructions 112 - Run with `-local github.com/tilt-dev` 113 - **[toast](https://github.com/stepchowfun/toast)**: `curl https://raw.githubusercontent.com/stepchowfun/toast/master/install.sh -LSfs | sh` (local development tasks) 114 115 ## Tilt APIServer 116 The Tilt APIServer is our new system for managing Tilt internals: 117 https://github.com/tilt-dev/tilt-apiserver 118 119 To add a new first-party type, run: 120 121 ``` 122 scripts/api-new-type.sh MyResourceType 123 ``` 124 125 and follow the instructions. 126 127 Once you've added fields for your type, run: 128 129 ``` 130 scripts/update-codegen.sh 131 ``` 132 133 to regenerate client code for reading and writing the new type. 134 135 ## Performance 136 137 ### Go Profile 138 139 Tilt exposes the standard Go pprof hooks over [HTTP](https://golang.org/pkg/net/http/pprof/). 140 141 To look at a 30-second CPU profile: 142 143 ``` 144 go tool pprof http://localhost:10350/debug/pprof/profile?seconds=30 145 ``` 146 147 To look at the heap profile: 148 149 ``` 150 go tool pprof http://localhost:10350/debug/pprof/heap 151 ``` 152 153 This opens a special REPL that lets you explore the data. 154 Type `web` in the REPL to see a CPU graph. 155 156 For more information on pprof, see https://github.com/google/pprof/blob/master/doc/README.md. 157 158 ## Web UI 159 160 `tilt up` runs a web server hosting a React single page application on port 10350 (customizable with `--port` or `TILT_PORT`). 161 162 ### Web Mode `(--web-mode)` 163 There are several possibilities for how Tilt serves the web assets based on the 164 build configuration. 165 166 #### Local (Dev) 167 By default, non-release builds of Tilt use a local Webpack dev server. 168 When Tilt first starts, it will launch the Webpack dev server for you. 169 If you immediately open the Tilt web UI, you might get an error message until Webpack has finished starting. 170 The page should auto-reload once Webpack is ready. 171 172 To force Tilt to use the Webpack dev server, launch with `tilt up --web-mode=local`. 173 174 #### Embedded 175 If bundled JS assets are available while building Tilt, they will be included in the binary and served via embedded mode. 176 This ensures the local Tilt server is self-contained and does not require internet access for the web UI. 177 178 This is the default for Tilt releases starting with v0.27.0. 179 180 To force Tilt to use the embedded assets, launch with `tilt up --web-mode=embedded`. 181 182 If unavailable, Tilt will refuse to start with an error: 183 ``` 184 Error: requested embedded mode, but assets are not available 185 ``` 186 To fix this, run `make build-js` and then re-build Tilt (e.g. with `make install`). 187 188 #### Cloud (Deprecated) 189 In the remote/production mode, all the HTML, CSS, and JS assets are served from our 190 [production bucket](https://console.cloud.google.com/storage/browser/tilt-static-assets). 191 192 This was the default for Tilt releases until v0.27.0. 193 194 To force Tilt to use the remote production assets, launch with `tilt up --web-mode=cloud`. 195 During development, this can speed up startup if you are not making changes to the frontend and does not require a local NodeJS toolchain. 196 197 ### Local Snapshot Mode 198 You can view a locally running Tilt session as though it was a snapshot by tweaking the URL to be `/snapshot/snapshot_id/overview`. 199 (The `snapshot_id` portion of the URL can be any valid identifier.) 200 For example, http://localhost:10350/snapshot/aaaa/overview. 201 202 Please note this uses a serialized version of the webview/snapshot generated by the Tilt server, so it might behave slightly differently than a real snapshot. 203 204 ### Lint (`prettier` + `eslint`) 205 To format all files with Prettier, run `make prettier` from the repo root or `yarn prettier` from `web/`. 206 207 To run lint checks with ESLint (and auto-fix any trivial issues), run `yarn eslint`. 208 209 To **verify** that there are no formatting/lint violations, but _not_ auto-fix, run `make check-js` from the repo root or `yarn check` from `web/`. 210 211 ### Tests 212 To run all tests, you can run `make test-js` from the repo root. 213 214 If you are actively developing, running `yarn test` from `web/` will launch Jest in interactive mode, 215 which can auto re-run affected tests and more. 216 217 #### Updating Jest Snapshot Tests 218 First, double check that the element render has changed _by design_ and not as a result of a regression. 219 220 The interactive mode of Jest will guide you to update snapshots. 221 See the [Jest snapshot testing documentation](https://jestjs.io/docs/en/snapshot-testing#interactive-snapshot-mode) for details. 222 223 ## Documentation 224 225 The user-facing landing page and documentation lives in 226 [the tilt.build repo](https://github.com/tilt-dev/tilt.build/). 227 228 We write our docs in Markdown and generate static HTML with [Jekyll](https://jekyllrb.com/). 229 230 Netlify will automatically deploy the docs to [the public site](https://docs.tilt.dev/) 231 when you merge to master. 232 233 For internal architecture, see [the Tilt Architecture Guide](internal/README.md). 234 235 ## Troubleshooting 236 ### Force Sign Out of Tilt Cloud 237 238 Once you've connected Tilt to Tilt Cloud via GitHub, you cannot sign out to break the connection. 239 But sometimes during development and testing, you need to do this. Remove the token file named `token` 240 located at `~/.windmill` on your machine. Restart Tilt, and you will be signed out. 241 242 ### Dependency Injection (`wire`) 243 244 Tilt uses [wire](https://github.com/google/wire) for dependency injection. It 245 generates all the code in the wire_gen.go files. 246 247 `make wire-dev` runs `wire` locally and ensures you have fast feedback when 248 rebuilding the generated code. 249 250 `make wire` runs `wire` in a container, to ensure you're using the correct 251 version. 252 253 What do you do if you added a dependency, and `make wire` is failing? 254 255 #### A Practical Guide to Fixing Your Dependency Injector 256 257 (This guide will work with any Dependency Injector - Dagger, Guice, etc - but is 258 written for Wire) 259 260 Step 1) DON'T PANIC. Fixing a dependency injector is like untangling a hair 261 knot. If you start pushing and pulling dependencies in the middle of the graph, 262 you will make it much worse. 263 264 Step 2) Run `make wire-dev` 265 266 Step 3) Look closely at the error message. Identify the "top" of the dependency 267 graph that is failing. So if your error message is: 268 269 ``` 270 wire: /go/src/github.com/tilt-dev/tilt/internal/cli/wire.go:182:1: inject wireRuntime: no provider found for github.com/tilt-dev/tilt/internal/k8s.MinikubeClient 271 needed by github.com/tilt-dev/tilt/internal/k8s.Client in provider set "K8sWireSet" (/go/src/github.com/tilt-dev/tilt/internal/cli/wire.go:44:18) 272 needed by github.com/tilt-dev/tilt/internal/container.Runtime in provider set "K8sWireSet" (/go/src/github.com/tilt-dev/tilt/internal/cli/wire.go:44:18) 273 wire: github.com/tilt-dev/tilt/internal/cli: generate failed 274 wire: at least one generate failure 275 ``` 276 277 then the "top" is the function wireRuntime at wire.go:182. 278 279 Step 4) Identify the dependency that is missing. In the above example, that 280 dependency is MinikubeClient. 281 282 Step 5) At the top-level provider function, add a provider for the missing 283 dependency. In this example, that means we add ProvideMinikubeClient to the 284 wire.Build call in wireRuntime. 285 286 Step 6) Go back to Step (2), and repeat until all errors are gone 287 288 Final Note: All dependency injection systems have a notion of groups of common 289 dependencies (in Wire, they're called WireSets). When fixing an injection error, 290 you generally want to move providers "up" the graph. i.e., remove them from 291 WireSets and add them to wire.Build calls. It's OK if this leads to lots of 292 duplication. Later, you can refactor them back down into common WireSets once 293 you've got it working. 294 295 ## Releasing 296 297 We use [goreleaser](https://goreleaser.com) to publish binaries. We never run it 298 locally. We run it in a CircleCI container. 299 300 To create a new release at tag `$TAG`, in the `~/go/src/github.com/tilt-dev/tilt` 301 directory, first switch to `master` and pull the latest changes with `git pull`. 302 And then: 303 304 ``` 305 git fetch --tags 306 git tag -a v0.x.y -m "v0.x.y" 307 git push origin v0.x.y 308 ``` 309 310 CircleCI will automatically start building your release, and notify the 311 #notify-circleci slack channel when it's done. The releaser generates a release on 312 at https://github.com/tilt-dev/tilt/releases, with a Changelog prepopulated automatically. 313 (Give it a few moments. It appears as a tag first, before turning into a full release.) 314 315 ### Verifying 316 You can build from source locally using the same toolchain as CI by running: 317 318 ```shell 319 make release-build 320 ``` 321 > You will need `toast` installed (see optional prerequisites) 322 323 This will take quite some time, but will create a `dist/` directory in the repo 324 root on your host machine. 325 Within the `dist/` directory, there will be directories for each of the OS and 326 architecture combinations, e.g. `dist/tilt-linux-amd64_linux_amd64/` for 64-bit 327 x86 Linux. 328 329 ### Version numbers 330 For pre-v1.0: 331 * If adding backwards-compatible functionality increment the patch version (0.x.Y). 332 * If adding backwards-incompatible functionality increment the minor version (0.X.y). We would probably **write a blog post** about this.