github.com/windmilleng/tilt@v0.13.6/CONTRIBUTING.md (about)

     1  # Hacking on Tilt
     2  
     3  So you want to make a change to `tilt`!
     4  
     5  ## Contributing
     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 its environs; please see our [**Code of Conduct**](https://docs.tilt.dev/code_of_conduct.html) for some rules that govern everyone's participation.
    10  
    11  Most of this page describes how to get set up making & testing changes. See a [YouTube walkthrough](https://youtu.be/oGC5O-BCBhc) showing some of the steps below, for macOS.
    12  
    13  Small PRs are better than large ones. If you have an idea for a major feature, please file
    14  an issue first. The [Roadmap](../../../../orgs/windmilleng/projects/3) has details on some of the upcoming
    15  features that we have in mind and might already be in-progress.
    16  
    17  ## Build Prereqs
    18  
    19  If you just want to build Tilt:
    20  
    21  - **[make](https://www.gnu.org/software/make/)**
    22  - **[go 1.14](https://golang.org/dl/)**
    23  - **[golangci-lint](https://github.com/golangci/golangci-lint)** (to run lint)
    24  - [yarn](https://yarnpkg.com/lang/en/docs/install/) (for JS resources)
    25  
    26  ## Test Prereqs
    27  
    28  If you want to run the tests:
    29  
    30  - **[docker](https://docs.docker.com/install/)** - Many of the `tilt` build steps do work inside of containers
    31    so that you don't need to install extra toolchains locally (e.g., the protobuf compiler).
    32  - **[kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)**
    33  - **[kustomize 2.0 or higher](https://github.com/kubernetes-sigs/kustomize)**: `go get -u sigs.k8s.io/kustomize`
    34  - **[helm](https://docs.helm.sh/using_helm/#installing-helm)**
    35  - **[docker compose](https://docs.docker.com/compose/install/)**: NOTE: this doesn't need to be installed separately from Docker on macOS
    36  - **[jq](https://stedolan.github.io/jq/download/)**
    37  
    38  ## Optional Prereqs
    39  
    40  Other development commands:
    41  
    42  - **[goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports?tab=doc)**: `go get -u golang.org/x/tools/cmd/goimports` (to sort imports, IDE-specific installation instructions in the link). You should configure goimports to run with `-local github.com/windmill/tilt`
    43  - **[toast](https://github.com/stepchowfun/toast)**: `curl https://raw.githubusercontent.com/stepchowfun/toast/master/install.sh -LSfs | sh` Used for generating some protobuf files
    44  - Our Python scripts are in Python 3.6.0. To run them:
    45    - **[pyenv](https://github.com/pyenv/pyenv#installation)**
    46    - **python**: `pyenv install`
    47    - if you're using GKE and get the error: "pyenv: python2: command not found", run:
    48      - `git clone git://github.com/concordusapps/pyenv-implict.git ~/.pyenv/plugins/pyenv-implict`
    49  
    50  ## Developing
    51  
    52  To check out Tilt for the first time, run:
    53  
    54  ```
    55  go get -u github.com/windmilleng/tilt/cmd/tilt
    56  ```
    57  
    58  The Go toolchain will checkout the Tilt repo somewhere on your GOPATH,
    59  usually under `~/go/src/github.com/windmilleng/tilt`.
    60  
    61  To run the fast test suite, run:
    62  
    63  ```
    64  make shorttest
    65  ```
    66  
    67  To run the slow test suite that interacts with Docker and builds real images, run:
    68  
    69  ```
    70  make test
    71  ```
    72  
    73  If you want to run an integration test suite that deploys servers to Kubernetes and
    74  verifies them, run:
    75  
    76  ```
    77  make integration
    78  ```
    79  
    80  To install `tilt` on PATH, run
    81  
    82  ```
    83  make install
    84  ```
    85  
    86  To start using Tilt, just run `tilt up` in any project with a `Tiltfile` -- i.e., NOT the root of the Tilt source code.
    87  There are plenty of toy projects to play with in the [integration](https://github.com/windmilleng/tilt/tree/master/integration) directory
    88  (see e.g. `./integration/oneup`), or check out one of these sample repos to get started:
    89  - [ABC123](https://github.com/windmilleng/abc123): Go/Python/JavaScript microservices generating random letters and numbers
    90  - [Servantes](https://github.com/windmilleng/servantes): a-little-bit-of-everything sample app with multiple microservices in different languages, showcasing many different Tilt behaviors
    91  - [Frontend Demo](https://github.com/windmilleng/tilt-frontend-demo): Tilt + ReactJS
    92  - [Live Update Examples](https://github.com/windmilleng/live_update): contains Go and Python examples of Tilt's [Live Update](https://docs.tilt.dev/live_update_tutorial.html) functionality
    93  - [Sidecar Example](https://github.com/windmilleng/sidecar_example): simple Python app and home-rolled logging sidecar
    94  
    95  ## Remove token to force signing out of Tilt Cloud
    96  
    97  Once you've connected Tilt to Tilt Cloud via GitHub, you cannot sign out to break the connection.
    98  But sometimes during development and testing, you need to do this. Remove the token file named `token` 
    99  located at `~/.windmill` on your machine. Restart Tilt, and you will be signed out.
   100  
   101  ## Performance
   102  
   103  ### Go Profile
   104  
   105  Tilt exposes the standard Go pprof hooks over [HTTP](https://golang.org/pkg/net/http/pprof/).
   106  
   107  To look at a 30-second CPU profile:
   108  
   109  ```
   110  go tool pprof http://localhost:10350/debug/pprof/profile?seconds=30
   111  ```
   112  
   113  To look at the heap profile:
   114  
   115  ```
   116  go tool pprof http://localhost:10350/debug/pprof/heap
   117  ```
   118  
   119  This opens a special REPL that lets you explore the data.
   120  Type `web` in the REPL to see a CPU graph.
   121  
   122  For more information on pprof, see https://github.com/google/pprof/blob/master/doc/README.md.
   123  
   124  ### Opentracing
   125  If you're trying to diagnose Tilt performance problems that lie between Tilt and your Kubernetes cluster (or between Tilt and Docker) traces can be helpful. The easiest way to get started with Tilt's [opentracing](https://opentracing.io/) support is to use the [Jaeger all-in-one image](https://www.jaegertracing.io/docs/1.11/getting-started/#all-in-one).
   126  
   127  ```
   128  $ docker run -d --name jaeger \
   129    -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
   130    -p 5775:5775/udp \
   131    -p 6831:6831/udp \
   132    -p 6832:6832/udp \
   133    -p 5778:5778 \
   134    -p 16686:16686 \
   135    -p 14268:14268 \
   136    -p 9411:9411 \
   137    jaegertracing/all-in-one:1.11
   138  ```
   139  
   140  Then start Tilt with the following flags:
   141  
   142  ```
   143  tilt up --trace --traceBackend jaeger
   144  ```
   145  
   146  When Tilt starts one of the first lines in the log output should contain a trace ID, like so:
   147  
   148  ```
   149  TraceID: 26256f1f6aa875e5
   150  ```
   151  
   152  You can use the Jaeger UI (by default running on http://localhost:16686/) to query for this span and see all of the traces for the current Tilt run. These traces are made available immediately as you use Tilt. You don't need to wait until after Tilt has stopped to get access to the tracing data.
   153  
   154  ## Web UI
   155  
   156  `tilt` uses a web interface for logs investigation.
   157  
   158  By default, the web interface runs on port 10350.
   159  
   160  When you use a released version of Tilt, all the HTML, CSS, and JS assets are served from our
   161  [production bucket](https://console.cloud.google.com/storage/browser/tilt-static-assets).
   162  
   163  When you build Tilt from head, the Tilt binary will default to development mode.
   164  When you run Tilt, it will run a webpack dev server as a separate process on port 46764,
   165  and reverse proxy all asset requests to the dev server.
   166  
   167  To manually control the assets served, you can use:
   168  
   169  ```
   170  tilt up --web-mode=local
   171  ```
   172  
   173  to force Tilt to use the webpack dev server, or you can use
   174  
   175  ```
   176  tilt up --web-mode=prod
   177  ```
   178  
   179  to force Tilt to use production assets.
   180  
   181  
   182  To run the server on an alternate port (e.g. 8001):
   183  
   184  ```
   185  tilt up --port=8001
   186  ```
   187  
   188  ## Documentation
   189  
   190  The landing page and documentation lives in
   191  [the tilt.build repo](https://github.com/windmilleng/tilt.build/).
   192  
   193  We write our docs in Markdown and generate static HTML with [Jekyll](https://jekyllrb.com/).
   194  
   195  Netlify will automatically deploy the docs to [the public site](https://docs.tilt.dev/)
   196  when you merge to master.
   197  
   198  ## Wire
   199  
   200  Tilt uses [wire](https://github.com/google/wire) for dependency injection. It
   201  generates all the code in the wire_gen.go files.
   202  
   203  `make wire-dev` runs `wire` locally and ensures you have fast feedback when
   204  rebuilding the generated code.
   205  
   206  `make wire` runs `wire` in a container, to ensure you're using the correct
   207  version.
   208  
   209  What do you do if you added a dependency, and `make wire` is failing?
   210  
   211  ### A Practical Guide to Fixing Your Dependency Injector
   212  
   213  (This guide will work with any Dependency Injector - Dagger, Guice, etc - but is
   214  written for Wire)
   215  
   216  Step 1) DON'T PANIC. Fixing a dependency injector is like untangling a hair
   217  knot. If you start pushing and pulling dependencies in the middle of the graph,
   218  you will make it much worse.
   219  
   220  Step 2) Run `make wire-dev`
   221  
   222  Step 3) Look closely at the error message. Identify the "top" of the dependency
   223  graph that is failing. So if your error message is:
   224  
   225  ```
   226  wire: /go/src/github.com/windmilleng/tilt/internal/cli/wire.go:182:1: inject wireRuntime: no provider found for github.com/windmilleng/tilt/internal/k8s.MinikubeClient
   227  	needed by github.com/windmilleng/tilt/internal/k8s.Client in provider set "K8sWireSet" (/go/src/github.com/windmilleng/tilt/internal/cli/wire.go:44:18)
   228  	needed by github.com/windmilleng/tilt/internal/container.Runtime in provider set "K8sWireSet" (/go/src/github.com/windmilleng/tilt/internal/cli/wire.go:44:18)
   229  wire: github.com/windmilleng/tilt/internal/cli: generate failed
   230  wire: at least one generate failure
   231  ```
   232  
   233  then the "top" is the function wireRuntime at wire.go:182.
   234  
   235  Step 4) Identify the dependency that is missing. In the above example, that
   236  dependency is MinikubeClient.
   237  
   238  Step 5) At the top-level provider function, add a provider for the missing
   239  dependency. In this example, that means we add ProvideMinikubeClient to the
   240  wire.Build call in wireRuntime.
   241  
   242  Step 6) Go back to Step (2), and repeat until all errors are gone
   243  
   244  Final Note: All dependency injection systems have a notion of groups of common
   245  dependencies (in Wire, they're called WireSets). When fixing an injection error,
   246  you generally want to move providers "up" the graph. i.e., remove them from
   247  WireSets and add them to wire.Build calls. It's OK if this leads to lots of
   248  duplication. Later, you can refactor them back down into common WireSets once
   249  you've got it working.
   250  
   251  ## Releasing
   252  
   253  We use [goreleaser](https://goreleaser.com) for releases.
   254  
   255  Requirements:
   256  - goreleaser: `go get -u github.com/goreleaser/goreleaser`
   257  - MacOS
   258  - Python
   259  - [gsutil](https://cloud.google.com/storage/docs/gsutil_install)
   260  - `GITHUB_TOKEN` env variable with repo scope
   261  
   262  Currently, releases have to be built on MacOS due to cross-compilation issues with Apple FSEvents.
   263  Cross-compiling a Linux target binary with a MacOS toolchain works fine.
   264  
   265  To create a new release at tag `$TAG`:
   266  
   267  ```
   268  git fetch --tags
   269  git tag -a v0.0.1 -m "my release"
   270  git push origin v0.0.1
   271  make release
   272  ```
   273  
   274  goreleaser will build binaries for the latest tag (using semantic version to
   275  determine "latest"). Check the current releases to figure out what the latest
   276  release ought to be.
   277  
   278  Add a [summary section](https://github.com/windmilleng/company/blob/master/user-support/README.md#releases) 
   279  in the release notes.
   280  
   281  After updating the release notes,
   282  update the [install](https://github.com/windmilleng/tilt.build/tree/master/docs/install.md) and [upgrade](https://github.com/windmilleng/tilt.build/blob/master/docs/upgrade.md) docs,
   283  the [default dev version](internal/cli/build.go),
   284  and the [installer version](scripts/install.sh).
   285  
   286  These should be updated as soon as possible to match the newest Tilt version
   287  available, especially since the Tilt update nudge will send people to the upgrade
   288  docs page to get the newest version. These version bump PRs can be merged
   289  immediately without review.
   290  
   291  To auto-generate new CLI docs, make sure you have tilt.build in a sibling directory of tilt, and run:
   292  
   293  ```
   294  make cli-docs
   295  ```
   296  
   297  ### Version numbers
   298  For pre-v1.0:
   299  * If adding backwards-compatible functionality increment the patch version (0.x.Y).
   300  * If adding backwards-incompatible functionality increment the minor version (0.X.y). We would probably **write a blog post** about this.
   301  
   302  ### Releasing the Synclet
   303  
   304  Releasing a synclet should be very infrequent, because the amount of things it
   305  does is small. (It's basically an optimization over `kubectl cp`, `kubectl
   306  exec`, and restarting a container.)
   307  
   308  To release a synclet, run `make synclet-release`. This will automatically:
   309  
   310  - Publish a new synclet image tagged with the current date
   311  - Update [sidecar.go](internal/synclet/sidecar/sidecar.go) with the new tag
   312  
   313  Then submit the PR. The next time someone releases Tilt, it will use the new image tag.
   314  
   315  
   316