Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: make UI dev easier #1278

Merged
merged 4 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"extensions": [
"golang.Go",
"dbaeumer.vscode-eslint",
"octref.vetur",
"zxh404.vscode-proto3",
"esbenp.prettier-vscode"
],
Expand All @@ -30,10 +29,6 @@
"label": "HTTP Port",
"onAutoForward": "notify"
},
"8081": {
"label": "UI Dev Port",
"onAutoForward": "notify"
},
"9000": {
"label": "GRPC Port",
"onAutoForward": "notify"
Expand Down
15 changes: 10 additions & 5 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,24 @@ After changing `flipt.proto`, you'll need to run `mage proto`. This will regener

The UI is built using [NPM](https://nodejs.org/en/) and [Vite](https://vitejs.dev/) and is also statically compiled into the Flipt binary using [go:embed](https://golang.org/pkg/embed/).

The UI code has been migrated to it's own repository: [flipt-ui](https:/flipt-io/flipt-ui).
The UI code has been migrated to it's own repository: [flipt-ui](https:/flipt-io/flipt-ui), clone it somewhere on your machine and follow the instructions in the README to get started.

TODO (WIP): More info on how to develop the UI within this repository.
To develop the project with the UI also in development mode (with hot reloading):

1. Run `npm run dev` where you have the `flipt-ui` repository checked out. This will start a development server on port `5173` and proxy API requests to the Flipt API on port `8080`.
2. Run `mage dev` from the this repository. This will create a dev build that will serve the UI from the development server, while still making it accessible on port `8080`.
3. Run the binary with the local config: `./bin/flipt --config ./config/local.yml`. This will enable CORS with the correct configuration and start the server on port `8080`.
4. Visit `http://localhost:8080` to see the UI.
5. Any changes made in the `flipt-ui` repository will be picked up by the development server and the UI will be reloaded.

### Ports

In development, the three ports that Flipt users are:
In development, the two ports that Flipt users are:

- `8080`: The port for the Flipt REST API
- `8081`: The port for the Flipt UI (via `npm run dev`)
- `9000`: The port for the Flipt GRPC Server

These three ports will be forwarded to your local machine automatically if you are developing Flipt in a VSCode Remote Container or GitHub Codespace.
These ports will be forwarded to your local machine automatically if you are developing Flipt in a VSCode Remote Container or GitHub Codespace.

## CDEs

Expand Down
6 changes: 3 additions & 3 deletions config/local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ log:
# ui:
# enabled: true

# cors:
# enabled: false
# allowed_origins: "*"
cors:
enabled: true
allowed_origins: ["*"]

# cache:
# enabled: false
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func NewHTTPServer(

// TODO: remove (deprecated as of 1.17)
if cfg.UI.Enabled {
u, err := fs.Sub(ui.UI, "dist")
u, err := fs.Sub(ui.UI, ui.Mount)
if err != nil {
return nil, fmt.Errorf("mounting UI: %w", err)
}
Expand Down
31 changes: 29 additions & 2 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,46 @@ func Bootstrap() error {
return goInstall(tools...)
}

// Build builds the project
// Build builds the project similar to a release build
func Build() error {
mg.Deps(Prep)
fmt.Println("Building...")

if err := build([]string{"-tags", "assets"}...); err != nil {
return err
}

fmt.Println("Done.")
fmt.Println("Run `./bin/flipt [--config config/local.yml]` to start Flipt")
return nil
}

// Dev builds the project for development, without bundling assets
func Dev() error {
mg.Deps(Clean)
fmt.Println("Building...")

if err := build(); err != nil {
return err
}

fmt.Println("Done.")
fmt.Println("Run `./bin/flipt [--config config/local.yml]` to start Flipt")
return nil
}

func build(args ...string) error {
buildDate := time.Now().UTC().Format(time.RFC3339)

gitCommit, err := sh.Output("git", "rev-parse", "HEAD")
if err != nil {
return fmt.Errorf("failed to get git commit: %w", err)
}

return sh.RunV("go", "build", "-trimpath", "-tags", "assets", "-ldflags", fmt.Sprintf("-X main.commit=%s -X main.date=%s", gitCommit, buildDate), "-o", "./bin/flipt", "./cmd/flipt/")
buildArgs := append([]string{"build", "-trimpath", "-ldflags", fmt.Sprintf("-X main.commit=%s -X main.date=%s", gitCommit, buildDate)}, args...)
buildArgs = append(buildArgs, "-o", "./bin/flipt", "./cmd/flipt/")

return sh.RunV("go", buildArgs...)
}

// Clean cleans up built files
Expand Down
6 changes: 5 additions & 1 deletion ui/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ package ui

import "embed"

var UI embed.FS
var (
//go:embed index.html
UI embed.FS
Mount = "."
)
7 changes: 5 additions & 2 deletions ui/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ package ui

import "embed"

//go:embed dist/*
var UI embed.FS
var (
//go:embed dist/*
UI embed.FS
Mount = "dist"
)
21 changes: 21 additions & 0 deletions ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en" className="h-full w-auto">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flipt</title>
<script type="module">
import RefreshRuntime from "http://localhost:5173/@react-refresh";
RefreshRuntime.injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;
window.__vite_plugin_react_preamble_installed__ = true;
</script>
<script type="module" src="http://localhost:5173/@vite/client"></script>
</head>
<body className="h-full bg-white antialiased">
<div id="root"></div>
</body>
<script type="module" src="http://localhost:5173/src/main.tsx"></script>
</html>