Commit Graph
69 Commits
Author SHA1 Message Date
64d9d00052 refactor: Add nightly test stability workflow (aka The Gauntlet) (#343)
Co-authored-by: Jonathan Yu <jonathan@coder.com>
Co-authored-by: Kyle Carberry <kyle@coder.com>
Co-authored-by: G r e y <vapurrmaid@pm.me>
2022-03-19 23:07:31 +00:00
Bryan edd8345658 fix: UX - Error logs in development from Empty state component (#466)
Fixes #452 

When the empty state is rendered with a non-textual element (which it turns out all our current empty states are, because they have a `<button />` component as a call to action), this noisy error log was showing up in the `console`:

```
Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
    at div
    at div
    at p
    at Typography (webpack-internal:///./node_modules/@material-ui/core/esm/Typography/Typography.js:166:28)
    at WithStyles (webpack-internal:///./node_modules/@material-ui/styles/esm/withStyles/withStyles.js:64:31)
    at div
    at StyledComponent (webpack-internal:///./node_modules/@material-ui/styles/esm/styled/styled.js:95:28)
    at EmptyState (webpack-internal:///./src/components/EmptyState/index.tsx:47:25)
...
    at ProjectsPage (webpack-internal:///./src/pages/projects/index.tsx:37:18)
    at Routes (webpack-internal:///./node_modules/react-router/index.js:275:5)
    at ThemeProvider (webpack-internal:///./node_modules/@material-ui/styles/esm/ThemeProvider/ThemeProvider.js:44:24)
    at UserProvider (webpack-internal:///./src/contexts/UserContext.tsx:100:55)
    at SWRConfig$1 (webpack-internal:///./node_modules/swr/dist/index.esm.js:501:23)
    at Router (webpack-internal:///./node_modules/react-router/index.js:209:15)
    at BrowserRouter (webpack-internal:///./node_modules/react-router-dom/index.js:118:5)
    at App
 ```

The issue was that the `description` prop could either be a `string` or an actual `React` component, but was always rendered as a child of a `<Typography />` component. The `<Typography>` component internally renders as a `<p>`, which is not valid to nest `<div>`s inside.

The fix is to not nest inside a `<Typography />` block, but an actual `<div />`.
2022-03-16 20:17:41 -07:00
Bryan 8b12e470d9 fix: CLI - Add log for daemon start (#464)
While going through the manual CLI flow with some people on the team, there was some confusion with the `coder daemon` command - the fact there was no output to confirm that the daemon started:

```
coder ~/coder (bryphe/fix/daemon-log) $ dist/coder_linux_amd64/coder daemon

```

This PR just adds a simple log to confirm that the daemon has started:
```
coder ~/coder (bryphe/fix/daemon-log) $ dist/coder_linux_amd64/coder daemon
2022-03-16 17:57:20.358 [INFO]  <daemon.go:53>  daemon started  {"url": "http://127.0.0.1:3000"}
```

Just throwing this out there. Feel free to reject if you have concerns about adding this @kylecarbs !
2022-03-16 13:39:57 -07:00
Bryan d8e530e1ec refactor: Add 'src' folder in 'site' (#445)
This refactoring re-organizes the `site` folder to have a nested `src` folder.

Originally, [we wanted to keep the directory structure shallow](https://github.com/coder/coder/pull/8#issuecomment-1009578910) - but there were two points that motivated this change to introduce the `src` level.

1. We have several non-`src` folders now (`e2e`, `static`, `html_templates`, `.storybook`)
2. Having a `src` folder makes it easier to run XState Typegen

So given those two data points - I believe it makes sense to revisit that and introduce a `src` folder.
2022-03-16 04:06:03 +00:00
Bryan 15beb98016 docs: Add additional commands (#455)
This adds a couple of missing pieces to the docs:
- More info about `./develop.sh`
- Steps to run the built coder binary manually
  - Starting the server
  - Logging in
  - Creating a project

I attempted to keep them relatively agnostic so they wouldn't be out of date immediately when https://github.com/coder/coder/pull/422 is merged
2022-03-16 03:55:21 +00:00
Bryan dfc353b1fd fix: Fix storybook blockers (#443)
I was just testing `storybook` out on `main`, and saw some of the components had errors:

<img width="1564" alt="image" src="https://user-images.githubusercontent.com/88213859/158444846-773420f5-261a-4853-abe1-66521ed19901.png">

There were two problems:
- The `<Workspace />` component had new arguments, that don't seem to be validated by `yarn storybook:build`
- The top-level `react-router-dom` is not available in storybook. 

After fixing these, all the storybook components work:

<img width="1304" alt="image" src="https://user-images.githubusercontent.com/88213859/158445124-eec51500-967d-4e24-823f-c21f6ea63ba1.png">
2022-03-15 11:29:32 -07:00
Bryan 97399f888d docs: Fix typo in README.md (#440) 2022-03-15 15:55:02 +00:00
Bryan 5e4d88a321 refactor: Move runtime dependencies out of devDependencies (#439)
@presleyp noticed that we have a lot of dependencies listed as `devDependencies` that should be actual `dependencies` - this PR moves them to the appropriate category.

Thanks for catching this @presleyp !
2022-03-14 17:24:26 -07:00
Bryan cadc2989c8 refactor: Remove now-unnecessary express & http-proxy-middleware packages (#437)
I was investigating some of the test failures in https://github.com/coder/coder/pull/429 - and realized that we actually don't need the `http-proxy-middleware` package anymore (or the `express` package). Of course - the failures were unrelated to that change, so this doesn't fix the CI failures that were encountered.

`http-proxy-middleware` and `express` were needed for our custom NextJS dev server, but that code was removed in #348 , so those dependencies are no longer explicitly required. We should just remove them to avoid the maintenance overhead.

Another clean-up / follow-up from #348
2022-03-14 20:59:47 +00:00
Bryan 20faf897c9 fix: Test flake when installing yarn dependencies on MacOS (#436)
This fixes #433 - a test flake in E2E (intermittent `ESOCKETTIMEDOUT` errors on MacOS).

The main issue is that, occasionally, for very large dependencies (like `@material-ui/icons`) - yarn can actually time out! We researched this in-depth in v1: https://github.com/coder/m/pull/10040 and fixed it successfully there, by increasing the timeout for yarn.

However, this also highlighted the fact that our `node_modules` caching behavior wasn't correct - we should very rarely see a timeout issue like this, because `@material-ui/icons` should be cached.

It turns out that we weren't falling back to the latest cached `node_modules` if there was a miss - so anytime the lock file changed, we'd  invalidate the cache, and not restore the previous one. This can be improved by using the [`restore-keys`](https://github.com/coder/m/pull/10040) parameter of the [`@actions/cache`](https://github.com/actions/cache)... and in fact we already do this for the `go` dependencies.

So this fix does two things:
- Improve the caching behavior, such that we should rarely have to install `@material-ui/icons` (and other large dependencies) 
- When we do have to install, update the timeout so that we can avoid random `ESOCKETTIMEDOUT` errors
2022-03-14 11:49:49 -07:00
Bryan ec077c6191 refactor: Migrate from Next.js to pure webpack config (#360)
Fix for #348 - migrate our NextJS project to a pure webpack project w/ a single bundle

- [x] Switch from `next/link` to `react-router-dom`'s link 

> This part was easy - just change the import to `import { Link } from "react-router-dom"` and `<Link href={...} />` to `<Link to={...} />`

- [x] Switch from `next/router` to `react-router-dom`'s paradigms (`useNavigation`, `useLocation`, and `useParams`)

> `router.push` can be converted to `navigate(...)` (provided by the `useNavigate` hook)
> `router.replace` can be converted `navigate(..., {replace: true})` 
>  Query parameters (`const { query } = useRouter`) can be converted to `const query = useParams()`)

- [x] Implement client-side routing with `react-router-dom`

> Parameterized routes in NextJS like `projects/[organization]/[project]` would look like:
> ```
>               <Route path="projects">
>                    <Route path=":organization/:project">
>                    <Route index element={<ProjectPage />} />
>                  </Route>
>               </Route>
> ```

I've hooked up a `build:analyze` command that spins up a server to show the bundle size:
<img width="1303" alt="image" src="https://user-images.githubusercontent.com/88213859/157496889-87c5fdcd-fad1-4f2e-b7b6-437aebf99641.png">

The bundle looks OK, but there are some opportunities for improvement - the heavy-weight dependencies, like React, ReactDOM, Material-UI, and lodash could be brought in via a CDN: https://stackoverflow.com/questions/50645796/how-to-import-reactjs-material-ui-using-a-cdn-through-webpacks-externals
2022-03-12 12:51:05 -08:00
Bryan 9f190418bb fix: Update routes for project page, workspace creation page, and workspace page (#415)
Some API routes were updated in https://github.com/coder/coder/pull/401, which impacted the UX - the flow is currently broken when trying to navigate to a project:

![2022-03-08 15 30 59](https://user-images.githubusercontent.com/88213859/157343533-3d08edf1-70d5-433b-b4a0-fe68875b1928.gif)

This fixes all the routes so that the complete project -> create workspace -> workspace page flow works:

![2022-03-08 16 18 57](https://user-images.githubusercontent.com/88213859/157348186-b9bde553-c602-484e-89bc-208a1d97f703.gif)

Because this had to touch a bunch of UI routes, I also opportunistically fixed #380 as part of this change.

Fixes #380
2022-03-09 13:22:43 -08:00
Bryan 86994dacb1 feat: Initial E2E test framework for v2 (#288)
This brings an initial E2E test (really, an integration test - it's only running the server locally, as opposed to against a deployment - but it'd be easy to point playwright to a deployment).

Demo gif:
![test2](https://user-images.githubusercontent.com/88213859/156078517-6cb4ef84-337b-4e16-a8bc-aea7d06dcbcb.gif)

This test exercises a minimal flow for login:
- Run the `coderd` binary to start a server on 3000
- Create an initial user as part of setup
- Go through the login flow and verify we land on the projects page

It will be useful to have to ensure that #360 doesn't introduce a regression in the login flow

Future E2E tests that would be useful:
- Create a project & verify it shows in the UI
- Create a workspace and verify it shows in the UI
2022-03-02 09:26:53 -08:00
Bryan 4f93c98f57 fix: coder project create -> coder projects create (#390)
While going through the create projects flow, I realized there's a typo on the projects page. 

The command should read `coder projects create`, but instead it is currently showing `coder project create`:
<img width="466" alt="Screen Shot 2022-03-01 at 5 31 19 PM" src="https://user-images.githubusercontent.com/88213859/156277646-6fc03977-6dda-4db4-9fce-e48b4b5efba3.png">

Fixing this typo will alleviate some confusion as we on-board developers to v2
2022-03-01 18:08:36 -08:00
Bryan 707016a3c5 refactor: Fix front-end lint issues (#347)
Noticed while running through the build steps (`make build`) that we were getting some lint warnings that weren't blocking build:
```sh
./pages/workspaces/[user]/[workspace].tsx
32:58  Warning: Unexpected any. Specify a different type.  @typescript-eslint/no-explicit-any
32:96  Warning: Unexpected any. Specify a different type.  @typescript-eslint/no-explicit-any

./components/Form/FormCloseButton.tsx
26:6  Warning: React Hook useEffect has a missing dependency: 'onClose'. Either include it or remove the dependency array. If 'onClose' changes too often, find the parent component that defines it and wrap that definition in useCallback.  react-hooks/exhaustive-deps

./components/Navbar/UserDropdown.tsx
38:14  Warning: Unnecessary conditional, value is always truthy.  @typescript-eslint/no-unnecessary-condition
68:10  Warning: Unnecessary conditional, value is always truthy.  @typescript-eslint/no-unnecessary-condition

./components/Redirect.tsx
20:6  Warning: React Hook useEffect has missing dependencies: 'router' and 'to'. Either include them or remove the dependency array.  react-hooks/exhaustive-deps

./components/SignIn/SignInForm.tsx
126:19  Warning: Unnecessary optional chain on a non-nullish value.  @typescript-eslint/no-unnecessary-condition
```

It turns out our ESLint config wasn't being picked up, so I fixed that (it wasn't properly named). This PR turns warnings-as-errors on, fixes the issues, and also removes the "Project Create" page, because it isn't used at this time.

Wanted to clean this up before on-boarding more FE developers
2022-02-22 20:10:02 -08:00
Bryan 2e12cb92e5 refactor: Add example of project with resource (#346)
This just adds the most minimal terraform script to provision a resource (the [`null_resource`](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource)) that doesn't require a cloud provider.

With this, we can test creating projects that have an associated resource:
<img width="464" alt="Screen Shot 2022-02-21 at 2 31 54 PM" src="https://user-images.githubusercontent.com/88213859/155033757-372cafbf-b35f-4988-8fbe-af276e22421c.png">
2022-02-22 18:55:45 -08:00
Bryan 1789ba01f7 refactor: Workspace Page - Add section components (#345)
Related #67 

This adds some placeholder `<WorkspaceSection />` components, so that we have a place to put things as we start to add more functionality to the Workspaces page.

Before, this was just the title:
<img width="1465" alt="image" src="https://user-images.githubusercontent.com/88213859/155033271-6fbe3dc1-3a9c-4305-bfe9-5bac73ac8b88.png">

Now, this PR introduces a component to host the sections:
<img width="1466" alt="Screen Shot 2022-02-21 at 2 19 12 PM" src="https://user-images.githubusercontent.com/88213859/155033002-55d853e2-50ab-4d6f-b5c4-ff35b8591a00.png">
2022-02-22 11:10:18 -08:00
Bryan 59ee22d368 refactor: Add a minimal example of a project with parameters (#331)
Thought it'd be helpful to show a bare-bones example of a project with a parameter, along with references to the Terraform docs so developers can learn about more interesting variable types (and ways to leverage them in expressions).

With this project, we can go through the `projects create` flow of setting a parameter:
<img width="677" alt="Screen Shot 2022-02-18 at 7 53 07 PM" src="https://user-images.githubusercontent.com/88213859/154785203-ab626268-0e51-48c3-b374-3d49d541042b.png">
2022-02-21 09:36:30 -08:00
Bryan 6170421044 fix: Install terraform in Docker image to unblock deploy (#319)
Fixes #287 and re-enables our deploy at https://proto.cdr.dev

- Installs `terraform` in our `images/coder/Dockerfile`
- Re-enables our `deploy` GH action

Example of successful deploy run: https://github.com/coder/coder/runs/5241614008?check_suite_focus=true
2022-02-18 09:07:28 -08:00
Bryan 4c71ff93eb refactor: Add minimal terraform project (#308)
I was thinking it might be nice to have some example projects (especially as we on-board new developers) to make it easy to create new projects.

This adds the most basic possible terraform module... just an output block. However, it's enough to run `coder projects create` and go through the whole lifecycle of creating a project and workspace (although, it's really boring since there are no parameters).
2022-02-17 21:11:48 -08:00
Bryan 3f7781403d feat: Login via CLI (#298)
Fixes #210 - this isPR implements `coder login` in the case where the default user is already created.

This change adds:
- A prompt in the case where there is not an initial user that opens the server URL + requests a session token
  - This ports over some code from v1 for the `openURL` and `isWSL` functions to support opening the browser
- A `/api/v2/api-keys` endpoint that can be `POST`'d to in order to request a new api key for a user
  - This route was inspired by the v1 functionality
- A `cli-auth` route + page that shows the generated api key
- Tests for the new code + storybook for the new UI

The `/cli-auth` route, like in v1, is very minimal:

<img width="624" alt="Screen Shot 2022-02-16 at 5 05 07 PM" src="https://user-images.githubusercontent.com/88213859/154384627-78ab9841-27bf-490f-9bbe-23f8173c9e97.png">

And the terminal UX looks like this:

![2022-02-16 17 13 29](https://user-images.githubusercontent.com/88213859/154385225-509c78d7-840c-4cab-8f1e-074fede8f97e.gif)
2022-02-17 20:09:33 -08:00
Bryan 9431c4549f fix: Redirect to workspaces page after creation (#309)
This is just a quick fix so that the redirection is correct after creating a workspace - so that we make it to our minimal 'workspaces' page. Mainly so we have a path for testing / onboarding more people.

Unfortunately the NextJS pages are a bit tricky to test - we don't have infra for it because of the special pathing requirements - we can potentially bring in a library like [next-page-tester](https://github.com/next-page-tester/next-page-tester) and create a separate test directory like `pages_test` - but since we may pick up the RFC to move away from Next, it doesn't seem like a useful effort.

With this, creating a project lands on our minimal workspaces page, and the links on the Projects page correctly navigate to the minimal workspaces page.
2022-02-17 09:44:02 -08:00
Bryan c2ad91bb74 fix: Redirect to '?redirect' query parameter after successful login (#307)
Fixes #304 
Unblocks #298 

After logging in, the login flow should redirect to a whatever path is specified by the `?redirect` query parameter. This is important for cases like #298 - where we need to set `?redirect=%2Fcli_auth`, but also really any case where the user is linked and might have to go back to the login screen.

The fix is simple - just check if the `redirect` query parameter is set, and if it is, use that as the path to redirect to on success. Also adds a test case - we had one checking that we redirect to the default (root `/`) url, but not one of the `?redirect` param
2022-02-17 08:35:36 -08:00
Bryan 4954a6b0a3 feat: Initial workspaces page route + skeleton (#220)
This implements an initial route for the workspaces page at `/workspaces/{user}/{workspace}`, and an additional storybook entry:

<img width="1723" alt="image" src="https://user-images.githubusercontent.com/88213859/153271281-801a5889-f60e-458c-809f-396a2d6385fa.png">

Just the header is rendering right now. Will be adding the additional sections prototyped in #219 in subsequent PRs

Related to https://github.com/coder/coder/issues/67
2022-02-15 20:49:56 -08:00
Bryan 6009c90d1d refactor: Rename 'expect' package to 'console' (#297)
Fixes #291 - renames the `expect` go package to `console`, and changes the api from `expect.NewTestConsole` to `console.New`, and a few other small changes to support the linter (ie, `ConsoleOpts` -> `Opts`)
2022-02-15 16:47:33 -08:00
Bryan 35291d358a fix: Forms - Add 'escape' button / key handler in forms (#240)
In v1, we had a quick and easy way to leave creation forms - an escape button (and key handler) in the top right corner.

This was especially helpful in cases where the form was long enough that the 'Cancel' button was off-screen.

This ports over that component into v2 and hooks up into our two existing forms:
<img width="977" alt="Screen Shot 2022-02-09 at 5 48 03 PM" src="https://user-images.githubusercontent.com/88213859/153321503-af957f2b-d674-4ebf-9ac5-97939cb9153f.png">

In addition, this adds test cases + a storybook story for it.
2022-02-15 16:43:27 -08:00
Bryan a86f2ee11d chore: Disable deploy action until fix is in (#290)
Related to #287 

Temporarily disable the deploy action until we have a fix available.
2022-02-15 09:24:40 -08:00
Bryan c9c03123eb fix: Run expect tests on Windows with conpty pseudo-terminal (#276)
This brings together a bunch of random, partially implemented packages for support of the new(ish) Windows [`conpty`](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/) API - such that we can leverage the `expect` style of CLI tests, but in a way that works in Linux/OSX `pty`s and Windows `conpty`.

These include:
- Vendoring the `go-expect` library from Netflix w/ some tweaks to work cross-platform
- Vendoring the `pty` cross-platform implementation from [waypoint-plugin-sdk](https://github.com/hashicorp/waypoint-plugin-sdk/tree/b55c787a65ff9b7d2b32cfae80681b78f8f2275e/internal/pkg/pty)
- Vendoring the `conpty` Windows-specific implementation from [waypoint-plugin-sdk](https://github.com/hashicorp/waypoint-plugin-sdk/tree/b55c787a65ff9b7d2b32cfae80681b78f8f2275e/internal/pkg/conpty)
- Adjusting the `pty` interface to work with `go-expect` + the cross-plat version

There were several limitations with the current packages:
- `go-expect` requires the same `os.File` (TTY) for input / output, but `conhost` requires separate file handles
- `conpty` does not handle input, only output
- The cross-platform `pty` didn't expose the full set of primitives needed for `console`

Therefore, the following changes were made:
- Handling of `stdin` was added to the `conpty` interface
- We weren't using the full extent of the `go-expect` interface, so some portions were removed (ie, exec'ing a process) to simplify our implementation and make it easier to extend cross-platform
- Instead of `console` exposing just a `Tty`, it exposes an `InTty` and `OutTty`, to help encapsulate the difference on Windows (on Linux, these point to the same pipe)

Future improvements:
- The `isatty` implementation doesn't support accurate detection of `conhost` pty's without an associated process. In lieu of a more robust check, I've added a `--force-tty` flag intended for test case use - that forces the CLI to run in tty mode.
- It seems the windows implementation doesn't support setting a deadline. This is needed for the expect.Timeout API, but isn't used by us yet.

Fixes #241
2022-02-14 17:05:40 -08:00
Bryan 64c14de7fe fix: Integrate front-end jest tests with datadog reporting (#286)
Fixes #244 

- Adds `jest-junit` 
- Configures `jest-junit` to output `junit.xml` in `site/test_results`
- Uploads the emitted `junit.xml` to datadog as part of the `test/js` workflow
2022-02-14 10:45:50 -08:00
Bryan df13fef161 fix: Remove 'Create Project' button, replace with CLI prompt (#245)
For black-triangle and alpha builds, we won't be able to create projects in the UI, because they require collecting and tar'ing a set of assets associated with the project - so the CLI is going to be our entry point for creating projects.

This shifts the UI to remove the 'Create Project' button, and adds a prompt to copy a command to run.

__Before:__
<img width="1134" alt="image" src="https://user-images.githubusercontent.com/88213859/153534269-58dc95bd-0417-4bed-8e62-e2b6f479da61.png">

__After:__
![2022-02-10 19 38 01](https://user-images.githubusercontent.com/88213859/153534227-d22bd786-8c43-4858-bda6-3d9d1d614711.gif)
2022-02-10 21:37:58 -08:00
Bryan c0d547b6a2 refactor: Add install script for coder CLI (#243)
This adds a `make install` target that copies the CLI and other coder binaries to `$GOPATH/bin` Intended to be helpful for developers who aren't familiar with `go` or the directory structure, in running `coder` CLI locally.
2022-02-10 20:32:00 -08:00
Bryan 277318bdb4 fix: Login - Add padding between username / password (#239)
This is just a minor fit & finish fix for login, to more closely emulate the styling of v1.

__Before:__
<img width="437" alt="Screen Shot 2022-02-09 at 4 16 05 PM" src="https://user-images.githubusercontent.com/88213859/153312547-04d0a15f-6f69-4365-8935-f1e8363b4cb6.png">

__After:__
<img width="446" alt="Screen Shot 2022-02-09 at 4 13 34 PM" src="https://user-images.githubusercontent.com/88213859/153312516-a4b4b67b-ed9c-43d2-b32d-3f3c746262d1.png">

While I was looking at this - removed a few currently-unnecessary styles and added a story for this component.
2022-02-09 20:18:29 -08:00
Bryan b6fcd8100d chore: Run 'yarn install' when building (#215)
I noticed when showing the development flow to a few engineers, there was one awkward step - you have to `cd site` and run `yarn install`, and then come back to root to `make build` or `./develop.sh`

This just adds `yarn install` as part of `make build` and `./develop.sh` - so whichever one is run first will start work.
2022-02-09 13:46:46 -08:00
Bryan c44d0369f6 fix: /projects endpoint returning null instead of empty array (#140)
While working on the projects page, I noticed the `/projects` endpoint would return 'null' instead of an empty array. An empty array would simplify the behavior on the client page.

There were already tests in place for this, but they only validated that the item's length is 0... and it turns out `len(nil)` is also `0`.

So this does a couple things:
- Updates the empty-project tests to check for `NotNil` as well
- Update the project endpoints to return an empty array if no rows are returned
- Remove the hack in `/projects` page for populating data, as it is no longer needed
2022-02-09 09:13:47 -08:00
Bryan d379767ad8 chore: Update stale.yml to only apply to pulls, not issues (#200)
Since we're using GH issues to track work (thanks @misskniss and @tjcran for setting this up!) - we probably don't want the stale bot to close untouched issues every month 😬 

I considered using a separate stale-duration (like, 365 days for issues) - but just turned it off now. Easy for us to change if we want to adjust the process.
2022-02-08 20:26:54 -08:00
Bryan 78bf4c6d21 feat: nextrouter pkg to handle nextjs routing rules (#167)
An issue came up last week... our `embed.go` strategy doesn't handle dynamic NextJS-style routes! This is a blocker, because I'm aiming to set up CD on Monday, and the v2 UI makes heavy use of dynamic routing.

As a potential solution, this implements a go pkg `nextrouter` that serves `html` files, but respecting the dynamic routing behavior of NextJS:
- Files that have square brackets - ie `[providers]` provide a single-level dynamic route
- Files that have `[[...` prefix - ie `[[...any]]` - are catch-all routes.
- Files should be preferred over folders (ie, `providers.html` is preferred over `/providers`)
- Fixes the trailing-slash bug we hit in the previous `embed` strategy

This also integrates with `slog.Logger` for tracing, and handles injecting template parameters - a feature we need in v1 and v2 to be able to inject stuff like CSRF tokens.

This implements testing by using an in-memory file-system, so that we can exercise all of these cases.

In addition, this adjust V2's `embed.go` strategy to use `nextrouter`, which simplifies that file considerably. I'm tempted to factor out the `secureheaders` logic into a separate package, too.

If this works OK, it could be used for V1 too (although that scenario is more complex due to our hybrid-routing strategy). Based on our FE variety meeting, there's always a chance we could move away from NextJS in v1 - if that's the case, this router will still work and be more tested than our previous strategy (it just won't make use of dynamic routing). So I figured this was worth doing to make sure we can make forward progress in V2.
2022-02-08 17:01:19 -08:00
Bryan b75ffdcc0b chore: Add dockerfile for deployment (#180)
This just adds a very simple dockerfile for deploying `coderd` (and later `provisionerd`). 

This adds a `deploy` directory at the root, and a `make docker/build` command to the makefile.

Thanks @jawnsy for the all the help 😄
2022-02-07 15:25:50 -08:00
Bryan bea708d28d refactor: Remove provisionerd from Makefile (#184)
This fixes an error that would occur in running `make build` - there isn't a `cmd/provisionerd/main.go` available at the moment.
2022-02-07 14:45:42 -08:00
Bryan e3089e99d9 refactor: Add <CodeBlock /> component (#168)
This ports over a component from v1 that is needed for the v2 workspace page, and adds theme colors for it:

<img width="772" alt="Screen Shot 2022-02-05 at 10 39 28 AM" src="https://user-images.githubusercontent.com/88213859/152654601-bab5acca-2e4a-4d53-890f-067a3b864040.png">

Component in storybook:
![image](https://user-images.githubusercontent.com/88213859/152654750-35565e5e-1f49-4b29-a140-cda757fb19aa.png)

By bringing in these components ahead of time - it'll make the workspaces page PR smaller.
2022-02-07 09:17:01 -08:00
Bryan 94f71feeba refactor: Add storybook + initial story (#118)
This hooks up `storybook`, which the front-end team has enjoyed using in the v1 codebase - it makes it quick and easy to view and test components in isolation.

The `<LoadingButton />` has a simple story added now, so if you run `yarn storybook`, you can preview it in various states:

![2022-01-31 19 24 24](https://user-images.githubusercontent.com/88213859/151908656-27dac0a8-9c6e-4353-ad25-3eafee979bd4.gif)

This will be helpful as we bring more front-end devs to help build v2 out.
2022-02-04 08:36:58 -08:00
Bryan d76737b30b fix: Adjust ./develop.sh script to run in ./site (#142)
Hopefully the last thing I missed in #128 ... this fixes the `./develop.sh` script and `site/dev.ts` to account for the new pathing of `package.json`.
2022-02-01 18:02:59 -08:00
Bryan 859407fd10 refactor: Update coverage ignore paths after moving files into /site (#139)
Unfortunately along with #133 I missed one other item in moving files to `/site` in #128 - ignoring new configuration files (and other folders) in our `jest.config.js`.

This caused our coverage numbers in front-end code to dip, because files that shouldn't be included (and previously weren't included) were now being tracked for coverage.
2022-02-01 15:26:48 -08:00
Bryan 56b3ec18f4 chore: Fix dependabot path after moving package.json -> site/package.json (#133)
Missed in #128 - need to update the `dependabot.yml` to point to the correct package.json, which was moved from `/package.json` -> `/site/package.json`
2022-02-01 14:44:01 -08:00
Bryan 78e652a268 refactor: Move package.json and other front-end collateral into 'site' (#128)
This refactors the front-end collateral to all live within `site` - so no `package.json` at the root.

The reason we had this initially is that the jest test run and NextJS actually require having _two_ different `tsconfig`s - Next needs `jsx:"preserve"`, while jest needs `jsx:"react"` - we were using `tsconfig`s at different levels at the hierarchy to manage this.

I changed this behavior to still use two different `tsconfig.json`s, which is mandatory - but just side-by-side in `site`.

Once that's fixed, it was easy to move everything into `site`

Follow up from: https://github.com/coder/coder/pull/118#discussion_r796244577
2022-02-01 13:34:43 -08:00
Bryan 38867b0ad3 fix: Re-enable parallel run of Postgres-backed tests (#119)
@kylecarbs and I were debugging a gnarly postgres issue over the weekend, and unfortunately it looks like it is still coming up occassionally: https://github.com/coder/coder/runs/5014420662?check_suite_focus=true#step:8:35 - so thought this might be a good testing Monday task.

Intermittently, the test would fail with something like a `401` - invalid e-mail, or a `409` - initial user already created. This was quite surprising, because the tests are designed to spin up their own, isolated database.

We tried a few things to debug this...

## Attempt 1: Log out the generated port numbers when running the docker image.

Based on the errors, it seemed like one test must be connecting to another test's database - that would explain why we'd get these conflicts! However, logging out the port number that came from docker always gave a unique number... and we couldn't find evidence of one database connecting to another.

## Attempt 2: Store the database in unique, temporary folder.

@kylecarbs and I found that the there was a [volume](https://github.com/docker-library/postgres/blob/a83005b407ee6d810413500d8a041c957fb10cf0/11/alpine/Dockerfile#L155) for the postgres data... so @kylecarbs implemented mounting the volume to a unique, per-test temporary folder in https://github.com/coder/coder/pull/89

It sounded really promising... but unfortunately we hit the issue again!

### Attempt 3... this PR

After we hit the failure again, we noticed in the `docker ps` logs something quite strange:
![image](https://user-images.githubusercontent.com/88213859/151913133-522a6c2e-977a-4a65-9315-804531ab7d77.png)

When the docker image is run - it creates two port bindings, an IPv4 and an IPv6 one. These _should be the same_ - but surprisingly, they can sometimes be different. It isn't deterministic, and seems to be more common when there are multiple containers running. Importantly, __they can overlap__ as in the above image. 

Turns out, it seems this is a docker bug: https://github.com/moby/moby/issues/42442 - which may be fixed in newer versions.

To work around this bug, we have to manipulate the port bindings (like you would with `-p`) at the command line. We can do this with `docker`/`dockertest`, but it means we have to get a free port ahead of time to know which port to map.

With that fix in - the `docker ps` is a little more sane:
![image](https://user-images.githubusercontent.com/88213859/151913432-5f86bc09-8604-4355-ad49-0abeaf8cc0fe.png)

...and hopefully means we can safely run the containers in parallel again.
2022-02-01 09:22:02 -08:00
Bryan bf90dede4f fix: cancel button on create-workspace page wasn't going to the right place (#117) 2022-01-31 19:08:10 -08:00
Bryan 7cf686c996 feat: Add Create Workspace Form (#73)
Fixes #38 

This adds a create-workspace form (with only 1 field, probably the simplest form ever 😄 )

![image](https://user-images.githubusercontent.com/88213859/151108220-8a540c75-e55b-49af-8199-c69394508700.png)

It currently redirects to a path `/workspaces/<unique id>`, but that isn't implemented yet - but you can see the workspace show up on the projects page.
2022-01-31 10:22:34 -08:00
Bryan f970e358fc chore: Set patch coverage to informational (always pass status check) (#75) 2022-01-26 14:24:11 -08:00
Bryan 0c46cbf406 fix: Use /projects as the landing page (#72)
Previously, there was a pseudo-workspaces page that was leftover from prototyping, but doesn't make sense in the revised flow.

Now, we have a `/projects` page, and after logging in, the user should be taken to that page:
![2022-01-25 20 13 58](https://user-images.githubusercontent.com/88213859/151102949-e756c995-eb43-42db-948d-931c2f0a1fca.gif)

This implements a client-side redirect to land on our `/projects` route.
2022-01-26 09:16:55 -08:00
Bryan 3047f251a8 feat: Implement simple Project Summary page (#71)
This implements a very simple Project Summary page (which lists workspaces):

![image](https://user-images.githubusercontent.com/88213859/151085991-bf5b101a-eadd-445b-9b42-1e98591e8343.png)

...which also has an empty state:

![image](https://user-images.githubusercontent.com/88213859/151086084-90d526a9-7661-46f0-b205-976518f978c1.png)

Fixes #66
2022-01-25 19:50:31 -08:00
Bryan c7fb16ebde feat: Initial Project Create Form ('/projects/create') (#60)
This implements a simple form for creating projects:

![2022-01-25 12 58 21](https://user-images.githubusercontent.com/88213859/151058767-be3672f6-e100-48c8-849e-cc6de94f3ebf.gif)

Fixes #65
2022-01-25 16:36:26 -08:00
Bryan bbd8b8ffa8 refactor: Refactor FormTextField to not require a HoC (#70)
Prompted from discussion here: https://github.com/coder/coder/pull/60/files#r792124373

Our current FormTextField implementation requires a [higher-order component](https://reactjs.org/docs/higher-order-components.html), which can be complicated to understand.

This experiments with moving it to not require being a HoC.

The only difference in usage is that sometimes, you need to provide the type like `<FormTextField<FormValues> form={form} formFieldName="some-field-in-form" />` - but it doesn't require special construction.
2022-01-25 14:00:19 -08:00
Bryan ec144d9f56 refactor: Fix path for creating initial user in dev script (#69)
Just a small fix in the `develop.sh` script to pick up the new create initial user route
2022-01-25 13:22:56 -08:00
Bryan 139828d594 refactor: 'create_initial_user.sh' helper script (#59)
I've been running this `curl` command a bunch of times every day (whenever I restart my dev server) - so moving it to a more convenient place.
2022-01-25 11:08:25 -08:00
Bryan b964cb0380 feat: Initial Projects listing page (#58)
This implements a simple Project listing page at `/projects` - just a table for a list of projects:

![image](https://user-images.githubusercontent.com/88213859/150906058-bbc49cfc-cb42-4252-bade-b8d48a986280.png)

...and an empty state:

![image](https://user-images.githubusercontent.com/88213859/150906882-03b0ace5-77c6-4806-b530-008769948867.png)

There isn't too much data to show at the moment. It'll be nice in the future to show the following fields and improve the UI with it:
- An icon
- A list of users using the project
- A description

However, this brings in a lot of scaffolding to make it easier to build pages like this (`/organizations`, `/workspaces`, etc).

In particular, I brought over a few things from v1:
- The `Hero` / `Header` component at the top of pages + sub-components
- A `Table` component for help rendering table-like UI + sub-components
- Additional palette settings that the `Hero`
2022-01-25 07:41:59 -08:00
Bryan 69d88b4a6d feat: Add Sign-out functionality (#46)
#37 implemented the Sign-_in_ flow, but there wasn't a Sign-_out_ flow as part of that PR (aside from letting the cookie expire... or manually deleting the cookie...), which is obviously not ideal.

This PR implements a basic sign-out flow, along with a very simple user dropdown:
![2022-01-21 18 09 14](https://user-images.githubusercontent.com/88213859/150620847-94e4d22f-1dcf-451e-8b4a-cec24702ea6c.gif)

Bringing in a few pruned down components for the `<UserDropdown />` to integrate into the `<NavBar />`.

In addition, this also implements a simple back-end API for `/logout` which just clears the session token.
2022-01-24 17:09:39 -08:00
Bryan e82e7b3f9f fix: Login - fix /api/v2/user cache race condition (#47)
While I was testing the Sign-out functionality in #46 , I found a bug on login. 

Sometimes, intermittently, the login wouldn't 'take' even though the login POST was successful and the subsequent GET to `/api/v2/user` was successful - the user would still be brought to the `/login` screen a second time:

![2022-01-21 19 52 31](https://user-images.githubusercontent.com/88213859/150623831-7ce33fca-97d5-4ea8-8301-9149def1ee40.gif)

^ I log-in, and then the login screen just resets, and logging in a second time works 🤔 

I tracked this down and found it is a new race condition that I inadvertently introduced when I migrated to SWR in #46. Because SWR caches responses based on the API path - we have to invalidate the cache for `/api/v2/user` when the user logins, otherwise we'll continue to serve the user-not-found error until SWR decides to retry. 

However, we weren't waiting for that cache-invalidation to go through - so there was the chance that an `/api/v2/user` request was still in-flight while we were redirecting after a successful login. If the request made it back prior to the redirect - login would work on the first try. If the request took longer - SWR would serve the stale, erroneous user from the cache.

Luckily the fix is simple - `mutate` in the SWR API returns a promise, so we can just wait for that to go through before redirecting. Unfortunately, though, this is tricky to exercise in a unit test because with the SWR model, the login logic is spread between `_app.tsx`, `UserContext.tsx`, and `SignInForm.tsx`, and the race condition involves an integration of all of those places. 

I found that there is a lint rule that can help protect us from making this mistake - [`typescript-eslint/no-floating-promises`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-floating-promises.md) (it's a lint rule we wanted to turn on in `coder/m`, too, actually - just a lot of work to clean up the code for it!), so I turned it on as part of this PR, and it caught a couple extra places to check.
2022-01-22 12:48:37 -08:00
Bryan 4183a4e01c feat: Initial Login flow (#42)
This just implements a basic sign-in flow, using the new endpoints in #29 :
![2022-01-20 12 35 30](https://user-images.githubusercontent.com/88213859/150418044-85900d1f-8890-4c60-baae-234342de71fa.gif)

This brings over several dependencies that are necessary:
- `formik`
- `yep`

Ports over some v1 code to bootstrap it:
- `FormTextField`
- `PasswordField`
- `CoderIcon`

And implements basic sign-in:
Fixes #37 
Fixes #43

This does not implement it navbar integration (importantly - there is no way to sign out yet, unless you manually delete your `session_token`). I'll do that in the next PR - figured this was big enough to get reviewed.
2022-01-21 11:34:26 -08:00
Bryan 7b9347bce6 chore: Add linter for typescript code (#45)
- Add and configure `eslint`
- Add to build pipeline
- Fix lint failures
2022-01-20 22:00:14 -08:00
Bryan 36b7b20e2a fix: Hydration warnings / mismatched styles due to SSR (#31)
While starting on the create workspace flow - I noticed some weird CSS issues.

In particular, intermittently, the web UI would render like this:
![image](https://user-images.githubusercontent.com/88213859/150072041-f1c6b9b2-941c-41a8-ad84-b7b163b3504f.png)

...and when that happened, there'd be an accompanying error in the console:

![image](https://user-images.githubusercontent.com/88213859/150072101-d98cb714-d133-4532-8a02-a7642d242a02.png)

The issue is that NextJS is trying to render the page on the server and use the styles - and sometimes the classnames mismatch between server-side and client-side rendering. We actually worked around this in `cdr/m` with a `<SafeHydration />` component and a custom `_document.tsx`

This change ports over both the component and custom `_document.tsx`. I noticed, in addition, I missed the favicons when switching to NextJS, so I brought those over too.
2022-01-19 13:24:30 -08:00
Bryan 4dc6e35c24 feat: Bundle UI into coderd; add ./develop.sh script (#28)
This change bundles the static assets like we have for v1 - using the [`embed`](https://pkg.go.dev/embed) go package. Fixes #22 

In addition, it sets up a development script that runs `coderd` locally and serves the front-end, with hot-reloading. The script used is `./develop.sh`:

![2022-01-14 17 30 14](https://user-images.githubusercontent.com/88213859/149603926-f673d3d3-ba12-4eda-bcdd-427252405480.gif)

> NOTE: The UI is still placeholder, of course. Need to start testing out a simple, placeholder flow for the new v2 world as a next step

Summary of changes:
- Add build steps for `go` in the `Makefile`
  - Add a step for production build, in which we use the `embed` tag
  - Add a step for development, which doesn't need the `embed` tag - so we don't need to build the front-end twice
- Add `next export` build step to output front-end artifacts in `out`
- Add a `site` package for `go`
  - Add `embed_static.go` and `embed.go`. This is mostly brought in as-is from v1, except removing some intercom/sentry CSP entries that we aren't using.
- Add a [next development server](https://nextjs.org/docs/advanced-features/custom-server)
- Add a `v2-dev` script, that runs `coderd` and the `next` dev server side-by-side
- Use the `site` package as the fallback handler.
- Add `.gitignore` entries for additional build collateral
2022-01-18 13:13:19 -08:00
Bryan 423611b001 chore: Add initial jest tests + code coverage (#13)
- Adds initial infra for running front-end tests (`jest`, `ts-jest`, `jest.config.js`, etc)
- Adds codecov integration front-end code
2022-01-13 18:48:23 -08:00
Bryan 92710ede54 chore: Add caching for node_modules (#19) 2022-01-13 09:11:52 -08:00
Bryan ace89161fb feat(cdr): Initial UI scaffolding
This is testing out [Approach 3](https://www.notion.so/coderhq/Workspaces-v2-Initial-UI-Scaffolding-3b07d2847eed48839a7e6f0f2bb9bf56#56256f25d2954897a8ee315f0820cedd) in the UI scaffolding RFC.

Fixes https://github.com/coder/coder/issues/11

The folder structure looks like:
- `site`
    - `components` (buttons, empty state, etc)
    - `pages` (large sections of UI -> composition of components)
    - `theme` (files defining our palette)

Several components were able to be brought in essentially unmodified:
- `SplitButton`
- `EmptyState`
- `Footer`
-  All the icons / logos
- Theming (removed several items that aren't necessary, yet, though)

Other components had more coupling, and need more refactoring:
- `NavBar`
- `Confetti`

Current State:

![2022-01-06 17 16 31](https://user-images.githubusercontent.com/88213859/148475521-96e080cc-1d33-4b8e-a434-29e388936e3f.gif)

For a full working app, there's potentially a lot more to bring in:
- User / Account Settings Stuff
- Users Page
- Organizations Page
(and all the supporting dependencies)
2022-01-12 14:25:12 -08:00
Bryan ec3685bc14 chore: Add documentation of our phased approach to the UX (#15) 2022-01-11 13:05:49 -08:00
Bryan 2769f4c2e0 chore: Formatting - bring .prettierrc over from cdr/m (#9)
This brings over the same `.prettierrc` we used in `cdr/m`, and runs the formatter w/ the new settings
2022-01-06 13:02:05 -08:00
Bryan 3a3161aa63 chore: Add semantic pull requests (#5)
Add a semantic-pull-requests configuration (like we have for `coder/m`), to validate commit messages.
2022-01-06 12:49:40 -08:00
Bryan 78973eaf3f chore: Initial GHA workflow (#1)
This implements an initial GitHub Actions workflow for us - to be run on PRs and on `main` commits.

This just implements a really simple `style/fmt` check - running `prettier` on the `README.md`.

I assumed we'll stick with using a top-level `Makefile` for commands like in `m` and `link` - but open to alternatives, too!

Since I was adding a `package.json` and `node_modules` for this, I realized we were missing `.gitignore`s, so I added some a subset of the ignore files from `coder/m`
2022-01-03 18:54:27 -08:00
Bryan Phelps 8203bf0d2d chore: Initial README 2022-01-03 18:52:07 +00:00