From 957912c9fc8fa88eac2ed5208a63fe105778e218 Mon Sep 17 00:00:00 2001 From: William Petit Date: Sun, 3 May 2020 19:19:28 +0200 Subject: [PATCH] Update release script to build/distribute backend --- .gitignore | 3 +- Dockerfile | 35 ++++++--- Makefile | 8 +- misc/dokku/Caddyfile | 6 -- misc/script/release.sh | 126 +++++++++++++++++++++++++++++++ server/go.mod | 4 +- server/internal/config/config.go | 6 +- server/internal/route/mount.go | 15 ++++ 8 files changed, 179 insertions(+), 24 deletions(-) delete mode 100644 misc/dokku/Caddyfile create mode 100755 misc/script/release.sh diff --git a/.gitignore b/.gitignore index c3f90ff..64de960 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /.vscode /server/bin /server/data -/server/vendor \ No newline at end of file +/server/vendor +/release \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7496990..af9c507 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,37 @@ -FROM alpine:3.11 AS build +FROM golang:1.13 AS build -RUN apk add --no-cache nodejs npm git make +ARG HTTP_PROXY= +ARG HTTPS_PROXY= +ARG http_proxy= +ARG https_proxy= + +RUN apt-get update && apt-get install -y build-essential git bash curl + +RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \ + && apt-get install -y nodejs COPY . /src + WORKDIR /src -RUN make install-deps \ - && make build +RUN ( cd client && npm install ) \ + && ( cd server && go mod vendor ) \ + && make ARCH_TARGETS=amd64 release -FROM alpine:3.11 +FROM busybox -COPY --from=build /src/client/dist /client +COPY --from=build /src/release/server-linux-amd64 /app -WORKDIR /client +WORKDIR /app -RUN apk add --no-cache caddy - -COPY misc/dokku/Caddyfile /client/Caddyfile COPY misc/dokku/CHECKS /client/CHECKS EXPOSE 80 -CMD ["caddy"] \ No newline at end of file +VOLUME /data + +ENV GUESSTIMATE_HTTP_ADDRESS=:80 +ENV GUESSTIMATE_HTTP_PUBLIC_DIR=/app/public +ENV GUESSTIMATE_DATA_PATH=/data/guesstimate.db + +CMD ["/app/bin/server", "-config", "config.yml"] \ No newline at end of file diff --git a/Makefile b/Makefile index e1667da..d0cc526 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ build-server: cd server && CGO_ENABLED=0 go build -mod=vendor -v -o bin/server ./cmd/server clean: - rm -rf dist + rm -rf client/dist server/bin release dokku-build: docker build \ @@ -27,4 +27,8 @@ dokku-run: dokku-deploy: $(if $(shell git config remote.dokku.url),, git remote add dokku $(DOKKU_URL)) - git push -f dokku $(shell git rev-parse HEAD):refs/heads/master \ No newline at end of file + git push -f dokku $(shell git rev-parse HEAD):refs/heads/master + +.PHONY: release +release: clean + @misc/script/release.sh \ No newline at end of file diff --git a/misc/dokku/Caddyfile b/misc/dokku/Caddyfile deleted file mode 100644 index 080bcca..0000000 --- a/misc/dokku/Caddyfile +++ /dev/null @@ -1,6 +0,0 @@ -*:80 -gzip -log stderr -rewrite { - to {path} {path}/ /index.html -} \ No newline at end of file diff --git a/misc/script/release.sh b/misc/script/release.sh new file mode 100755 index 0000000..81b67f9 --- /dev/null +++ b/misc/script/release.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +set -eo pipefail + +OS_TARGETS=( linux ) +ARCH_TARGETS=${ARCH_TARGETS:-amd64 arm 386} + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +PROJECT_DIR="$DIR/../.." + +function build { + + local name=$1 + local srcdir=$2 + local os=$3 + local arch=$4 + + local dirname="$name-$os-$arch" + local destdir="$PROJECT_DIR/release/$dirname" + + rm -rf "$destdir" + mkdir -p "$destdir" + + echo "building $dirname..." + + CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" go build \ + -mod=vendor \ + -ldflags="-s -w -X 'main.GitRef=$(current_commit_ref)' -X 'main.ProjectVersion=$(current_version)' -X 'main.BuildDate=$(current_date)'" \ + -gcflags=-trimpath="${PWD}" \ + -asmflags=-trimpath="${PWD}" \ + -o "$destdir/bin/$name" \ + "$srcdir" +} + +function current_date { + date '+%Y-%m-%d %H:%M' +} + +function current_commit_ref { + git log -n 1 --pretty="format:%h" +} + +function current_version { + local latest_tag=$(git describe --abbrev=0 2>/dev/null) + echo ${latest_tag:-0.0.0} +} + +function copy { + + local name=$1 + local os=$2 + local arch=$3 + local src=$4 + local dest=$5 + + local dirname="$name-$os-$arch" + local destdir="$PROJECT_DIR/release/$dirname" + + echo "copying '$src' to '$destdir/$dest'..." + + mkdir -p "$(dirname $destdir/$dest)" + + cp -rfL $src "$destdir/$dest" + +} + +function dump_default_conf { + # Generate and copy configuration file + local command=$1 + local os=$2 + local arch=$3 + local tmp_conf=$(mktemp) + + go run "$PROJECT_DIR/server/cmd/$command" -dump-config > "$tmp_conf" + copy "$command" $os $arch "$tmp_conf" "config.yml" + rm -f "$tmp_conf" "$patched_conf" +} + +function compress { + + local name=$1 + local os=$2 + local arch=$3 + + local dirname="$name-$os-$arch" + local destdir="$PROJECT_DIR/release/$dirname" + + echo "compressing $dirname..." + tar -czf "$destdir.tar.gz" -C "$destdir/../" "$dirname" +} + +function build_guesstimate_client { + ( + cd client + npm run build + ) +} + +function release_guesstimate { + local os=$1 + local arch=$2 + + # Build and copy server files + ( + cd server + build 'server' "$PROJECT_DIR/server/cmd/server" $os $arch + dump_default_conf 'server' $os $arch + ) + + copy 'server' $os $arch "$PROJECT_DIR/client/dist" "public" + copy 'server' $os $arch "$PROJECT_DIR/README.md" "README.md" + compress 'server' $os $arch + +} + +function main { + build_guesstimate_client + + for os in ${OS_TARGETS[@]}; do + for arch in ${ARCH_TARGETS[@]}; do + release_guesstimate $os $arch + done + done +} + +main \ No newline at end of file diff --git a/server/go.mod b/server/go.mod index d6a2e15..c6e2517 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,9 +5,9 @@ go 1.14 require ( github.com/asdine/storm/v3 v3.1.1 github.com/caarlos0/env/v6 v6.2.1 - github.com/davecgh/go-spew v1.1.1 + github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-chi/chi v4.1.1+incompatible - github.com/gorilla/websocket v1.4.2 + github.com/gorilla/websocket v1.4.2 // indirect github.com/pkg/errors v0.9.1 gitlab.com/wpetit/goweb v0.0.0-20200418152305-76dea96a46ce golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect diff --git a/server/internal/config/config.go b/server/internal/config/config.go index 3d94d77..788c52a 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -16,7 +16,8 @@ type Config struct { } type HTTPConfig struct { - Address string `yaml:"address" env:"GUESSTIMATE_HTTP_ADDRESS"` + Address string `yaml:"address" env:"GUESSTIMATE_HTTP_ADDRESS"` + PublicDir string `yaml:"publicDir" env:"GUESSTIMATE_PUBLIC_DIR"` } type DataConfig struct { @@ -55,7 +56,8 @@ func NewDumpDefault() *Config { func NewDefault() *Config { return &Config{ HTTP: HTTPConfig{ - Address: ":8081", + Address: ":8081", + PublicDir: "public", }, Data: DataConfig{ Path: "guesstimate.db", diff --git a/server/internal/route/mount.go b/server/internal/route/mount.go index 2224210..da26801 100644 --- a/server/internal/route/mount.go +++ b/server/internal/route/mount.go @@ -1,8 +1,12 @@ package route import ( + "net/http" + "path" + "forge.cadoles.com/wpetit/guesstimate/internal/config" "github.com/go-chi/chi" + "gitlab.com/wpetit/goweb/static" ) func Mount(r *chi.Mux, config *config.Config) error { @@ -13,5 +17,16 @@ func Mount(r *chi.Mux, config *config.Config) error { r.Delete("/projects/{projectID}", handleDeleteProject) }) + clientIndex := path.Join(config.HTTP.PublicDir, "index.html") + + serveClientIndex := func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, clientIndex) + } + + r.Get("/p/*", serveClientIndex) + + notFoundHandler := r.NotFoundHandler() + r.Get("/*", static.Dir(config.HTTP.PublicDir, "", notFoundHandler)) + return nil }