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.