From 045e25db2ee8e4d23820e1e64a97615bbfe12c0a Mon Sep 17 00:00:00 2001 From: Guilherme Oenning Date: Sun, 21 Mar 2021 20:31:45 +0000 Subject: [PATCH] tooling: replace mage with standard make and simplify docker setup (#923) --- .github/workflows/fider.yml | 45 ++++++----- CONTRIBUTING.md | 23 ++---- Dockerfile | 45 +++++++---- Makefile | 79 ++++++++++++++++++ go.mod | 1 - go.sum | 3 +- magefile.go | 156 ------------------------------------ tools.go | 5 +- 8 files changed, 145 insertions(+), 212 deletions(-) create mode 100644 Makefile delete mode 100644 magefile.go diff --git a/.github/workflows/fider.yml b/.github/workflows/fider.yml index fe21ed29a..74f0c1009 100644 --- a/.github/workflows/fider.yml +++ b/.github/workflows/fider.yml @@ -12,22 +12,19 @@ jobs: test-ui: name: test-ui runs-on: ubuntu-latest - container: - image: getfider/githubci:0.0.5 - steps: - - name: checkout code - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v1 + with: + node-version: 14.x - run: npm ci - - run: mage lint:ui - - run: mage test:ui + - run: make lint-ui + - run: make test-ui test-server: name: test-server runs-on: ubuntu-latest - container: - image: getfider/githubci:0.0.5 - services: minio: image: getfider/minio:0.0.2 @@ -47,25 +44,33 @@ jobs: options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - - name: checkout code - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - name: Use Go 1.16.2 + uses: actions/setup-go@v2 + with: + go-version: 1.16.2 + - name: Use Node.js 14.x + uses: actions/setup-node@v1 + with: + node-version: 14.x - run: npm ci # required for esbuild - - run: mage lint:server - - name: mage test:server + - name: install golangci-lint + run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.38.0 + - name: install godotenv + run: go install github.com/joho/godotenv/cmd/godotenv + - run: make lint-server + - name: make test-server run: | mkdir ./dist - mage test:server + make test-server env: - BLOB_STORAGE_S3_ENDPOINT_URL: http://minio:9000 - DATABASE_URL: postgres://fider_ci:fider_ci_pw@postgres:5432/fider_ci?sslmode=disable + BLOB_STORAGE_S3_ENDPOINT_URL: http://localhost:9000 + DATABASE_URL: postgres://fider_ci:fider_ci_pw@localhost:5432/fider_ci?sslmode=disable build: name: build runs-on: ubuntu-latest needs: [test-server, test-ui] - container: - image: getfider/githubci:0.0.5 - steps: - name: checkout code uses: actions/checkout@v1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4812d60cb..efa8f778b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,11 +31,10 @@ If you know these technologies or would like to learn them, lucky you! This is t 2. navigate into the cloned repository. 3. run `go install github.com/cosmtrek/air` to install air, a cli tool for live reload, when you change the code, it automatically recompiles the application. 4. run `go install github.com/joho/godotenv/cmd/godotenv` to install godotenv, a cli tool to load environment variables from a `.env` so that you don't have to change your machine environment variables. -5. run `go install github.com/magefile/mage` to install mage, a cross-platform Make alternative. -6. run `go install github.com/golangci/golangci-lint/cmd/golangci-lint` to install golangci-lint, a linter for Go apps. -7. run `npm install` to install client side packages. -8. run `docker-compose up -d` to start a local PostgreSQL database and Local SMTP (with [MailHog](https://github.com/mailhog/MailHog)) on Docker. -9. run `cp .example.env .env` to create a local environment configuration file. +5. run `go install github.com/golangci/golangci-lint/cmd/golangci-lint` to install golangci-lint, a linter for Go apps. +6. run `npm install` to install client side packages. +7. run `docker-compose up -d` to start a local PostgreSQL database and Local SMTP (with [MailHog](https://github.com/mailhog/MailHog)) on Docker. +8. run `cp .example.env .env` to create a local environment configuration file. - **Important:** Fider has a strong dependency on an email delivery service. For easier local development, the docker-compose file already provides a fake SMTP server running at port **1026** and a UI (to check sent emails) at http://localhost:8026. The `.example.env` is already @@ -46,12 +45,12 @@ If you know these technologies or would like to learn them, lucky you! This is t #### 3. To start the application -1. run `mage watch` to start the application on watch mode. The application will be reloaded every time a file is changed. Alternatively, it's also possible to start Fider by running `mage build` and `mage run`. +1. run `make watch-ui` and `make watch-server` to start both the server and ui on watch mode. The application will be reloaded every time a file is changed. Alternatively, it's also possible to start Fider by running `make build` and `make run`. 2. Navigate to `http://localhost:3000/` and 🎉! You should see the sign up page of Fider! #### 4. To run the unit tests: -1. run `mage test` to run both UI and Server unit tests. +1. run `make test` to run both UI and Server unit tests. ## Common Issues @@ -61,12 +60,4 @@ This is a known [Issue #434](https://github.com/getfider/fider/issues/434). If y #### 2. godotenv: not found -This happens when godotenv was not (or incorrectly) installed. Install it by running `go get github.com/joho/godotenv/cmd/godotenv/`. - -#### 3. mage watch throws 'too many open files' error - -macOS has a small limit on how many files can be open at the same time. This limit is usually OK for most users, but developers tools usuage require a larger limit. [Learn how to resolve this](https://www.macobserver.com/tips/deep-dive/evade-macos-many-open-files-error-pushing-limits/). - -#### 4. mage isn't found even after installing - -Include %GOPATH%\bin in PATH environment variable and restart the terminal +This happens when godotenv was not (or incorrectly) installed. Install it by running `go get github.com/joho/godotenv/cmd/godotenv/`. \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 470cb6d7d..f3a5b9cd7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,30 @@ -# Build Step -FROM getfider/githubci:0.0.5 AS builder +##################### +### Server Build Step +##################### +FROM golang:1.16.2-buster AS server-builder -RUN mkdir /app -WORKDIR /app +RUN mkdir /server +WORKDIR /server + +COPY . . +RUN GOOS=linux GOARCH=amd64 make build-server + +################# +### UI Build Step +################# +FROM node:14-buster AS ui-builder + +RUN mkdir /ui +WORKDIR /ui COPY . . RUN npm ci -RUN GOOS=linux GOARCH=amd64 mage build +RUN make build-ssr +RUN make build-ui -# Runtime Step +################ +### Runtime Step +################ FROM debian:buster-slim RUN apt-get update @@ -17,14 +33,15 @@ RUN apt-get install -y ca-certificates RUN mkdir /app WORKDIR /app -COPY --from=builder /app/favicon.png /app -COPY --from=builder /app/migrations /app/migrations -COPY --from=builder /app/views /app/views -COPY --from=builder /app/dist /app/dist -COPY --from=builder /app/LICENSE /app -COPY --from=builder /app/robots.txt /app -COPY --from=builder /app/ssr.js /app -COPY --from=builder /app/fider /app +COPY --from=server-builder /server/migrations /app/migrations +COPY --from=server-builder /server/views /app/views +COPY --from=server-builder /server/LICENSE /app +COPY --from=server-builder /server/fider /app + +COPY --from=ui-builder /ui/favicon.png /app +COPY --from=ui-builder /ui/dist /app/dist +COPY --from=ui-builder /ui/robots.txt /app +COPY --from=ui-builder /ui/ssr.js /app EXPOSE 3000 diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..cb744aaa7 --- /dev/null +++ b/Makefile @@ -0,0 +1,79 @@ +## This is a self-documented Makefile. For usage information, run `make help`: +## +## For more information, refer to https://suva.sh/posts/well-documented-makefiles/ + +LDFLAGS += -X main.buildtime=$(shell date -u "+%Y-%m-%dT%H:%M:%S")" +LDFLAGS += -X main.buildnumber=${GITHUB_RUN_ID}" + +##@ Running + +run: ## Run Fider + godotenv -f .env ./fider + +migrate: ## Run all database migrations + godotenv -f .env ./fider migrate + + + +##@ Building + +build: build-server build-ssr build-ui ## Build server and ui + +build-server: ## Build server + go build -ldflags '-s -w $(LDFLAGS)' -o fider . + +build-ui: ## Build all UI assets + NODE_ENV=production npx webpack-cli + +build-ssr: ## Build SSR script + NODE_ENV=production node esbuild.config.js + + + +##@ Testing + +test: test-server test-ui ## Test server and ui code + +test-server: build-server build-ssr ## Run all server tests + godotenv -f .test.env ./fider migrate + godotenv -f .test.env go test ./... -race + +test-ui: ## Run all UI tests + TZ=GMT npx jest ./public + +coverage-server: build-server build-ssr ## Run all server tests (with code coverage) + godotenv -f .test.env ./fider migrate + godotenv -f .test.env go test ./... -coverprofile=cover.out -coverpkg=all -p=8 -race + + + +##@ Running (Watch Mode) + +watch-server: build-server migrate ## Build and run server in watch mode + air -c air.conf + +watch-ui: clean ## Build and run server in watch mode + npx webpack-cli -w + + + +##@ Linting + +lint: lint-server lint-ui ## Lint server and ui + +lint-server: ## Lint server code + golangci-lint run + +lint-ui: ## Lint ui code + npx tslint -c tslint.json 'public/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' + + + +##@ Miscellaneous + +clean: ## Remove all build-generated content + rm -rf ./dist + rm -f ssr.js + +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/go.mod b/go.mod index 94e2b9b27..cd954afaf 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/joho/godotenv v1.3.0 github.com/julienschmidt/httprouter v1.3.0 github.com/lib/pq v1.9.0 - github.com/magefile/mage v1.11.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/russross/blackfriday v1.6.0 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 diff --git a/go.sum b/go.sum index 88cbe6941..c64d93206 100644 --- a/go.sum +++ b/go.sum @@ -331,9 +331,8 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= -github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= diff --git a/magefile.go b/magefile.go deleted file mode 100644 index 2ce265fdb..000000000 --- a/magefile.go +++ /dev/null @@ -1,156 +0,0 @@ -// +build mage - -package main - -import ( - "fmt" - "os" - "os/exec" - "runtime" - "time" - - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" -) - -// warning shown when at least one dependency is not installed -var missingDepsWarning = `Dependencies %v are missing. Please install them and try again. -To learn how, visit our contributors guide: https://github.com/getfider/fider/blob/master/CONTRIBUTING.md. -` - -// required dependencies for building fider -var requiredDeps = []string{ - "air", - "godotenv", - "docker", - "npm", - "node", - "mage", - "golangci-lint", -} -var buildTime = time.Now().Format("2006.01.02.150405") -var buildNumber = os.Getenv("GITHUB_RUN_ID") -var exeName = "fider" - -var Aliases = map[string]interface{}{ - "build": Build.All, - "test": Test.All, - "watch": Watch.All, - "lint": Lint.All, -} - -func init() { - os.Setenv("MAGEFILE_VERBOSE", "true") - if runtime.GOOS == "windows" { - exeName = "fider.exe" - } - - missingDeps := missingDependencies() - if len(missingDeps) > 0 { - fmt.Printf(missingDepsWarning, missingDeps) - os.Exit(1) - } -} - -func Run() error { - return sh.Run("godotenv", "-f", ".env", "./"+exeName) -} - -func Migrate() error { - return sh.Run("godotenv", "-f", ".env", "./"+exeName, "migrate") -} - -func Clean() error { - os.RemoveAll("./dist") - return os.Mkdir("./dist", 0777) -} - -type Watch mg.Namespace - -func (Watch) All() { - mg.SerialDeps(Clean, Build.Server, Migrate) - mg.Deps(Watch.Server, Watch.UI) -} - -func (Watch) UI() error { - return sh.Run("npx", "webpack-cli", "-w") -} - -func (Watch) Server() error { - return sh.Run("air", "-c", "air.conf") -} - -type Build mg.Namespace - -func (Build) All() { - mg.Deps(Build.Server, Build.UI, Build.SSR) -} - -func (Build) SSR() error { - env := map[string]string{"NODE_ENV": "production"} - return sh.RunWith(env, "node", "esbuild.config.js") -} - -func (Build) Server() error { - env := map[string]string{ - "GOOS": runtime.GOOS, - "GOARCH": runtime.GOARCH, - } - ldflags := "-s -w -X main.buildtime=" + buildTime + " -X main.buildnumber=" + buildNumber - return sh.RunWith(env, "go", "build", "-ldflags", ldflags, "-o", exeName, ".") -} - -func (Build) UI() error { - mg.Deps(Clean) - env := map[string]string{"NODE_ENV": "production"} - return sh.RunWith(env, "npx", "webpack-cli") -} - -type Test mg.Namespace - -func (Test) All() { - mg.Deps(Test.Server, Test.UI) -} - -func (Test) Coverage() error { - mg.Deps(Build.Server) - sh.Run("godotenv", "-f", ".test.env", "./"+exeName, "migrate") - return sh.Run("godotenv", "-f", ".test.env", "go", "test", "./...", "-coverprofile=cover.out", "-coverpkg=all", "-p=8", "-race") -} - -func (Test) Server() error { - mg.Deps(Build.Server, Build.SSR) - sh.Run("godotenv", "-f", ".test.env", "./"+exeName, "migrate") - return sh.Run("godotenv", "-f", ".test.env", "go", "test", "./...", "-race") -} - -func (Test) UI() error { - env := map[string]string{"TZ": "GMT"} - return sh.RunWith(env, "npx", "jest", "./public") -} - -type Lint mg.Namespace - -func (Lint) All() { - mg.Deps(Lint.Server, Lint.UI) -} - -func (Lint) UI() error { - return sh.Run("npx", "tslint", "-c", "tslint.json", "'public/**/*.{ts,tsx}'", "'tests/**/*.{ts,tsx}'") -} - -func (Lint) Server() error { - return sh.Run("golangci-lint", "run") -} - -// Utils -func missingDependencies() []string { - var missingDeps []string - for _, dep := range requiredDeps { - _, err := exec.LookPath(dep) - if err != nil { - missingDeps = append(missingDeps, dep) - } - } - return missingDeps -} diff --git a/tools.go b/tools.go index f7d3ce7a2..42ecfaaaa 100644 --- a/tools.go +++ b/tools.go @@ -3,8 +3,7 @@ package tools import ( - _ "github.com/magefile/mage" - _ "github.com/joho/godotenv/cmd/godotenv" _ "github.com/cosmtrek/air" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" -) \ No newline at end of file + _ "github.com/joho/godotenv/cmd/godotenv" +)