From 249d48390ab8370af8047836e45bb9c08d1c7be5 Mon Sep 17 00:00:00 2001 From: Nicolai Ommer Date: Sun, 23 Apr 2023 20:34:22 +0200 Subject: [PATCH] Update project structure --- .circleci/config.yml | 153 ++++++++++++--------- .dockerignore | 16 ++- .editorconfig | 8 +- .github/release.yml | 11 ++ .gitignore | 28 ++-- Dockerfile | 23 ---- Makefile | 30 ++++ README.md | 20 ++- cli.Dockerfile | 13 -- cmd/ssl-vision-cli/Dockerfile | 14 ++ cmd/ssl-vision-client/Dockerfile | 22 +++ frontend/package-lock.json | 4 +- install.sh | 13 -- generateProto.sh => tools/generateProto.sh | 0 14 files changed, 213 insertions(+), 142 deletions(-) create mode 100644 .github/release.yml delete mode 100644 Dockerfile create mode 100644 Makefile delete mode 100644 cli.Dockerfile create mode 100644 cmd/ssl-vision-cli/Dockerfile create mode 100644 cmd/ssl-vision-client/Dockerfile delete mode 100755 install.sh rename generateProto.sh => tools/generateProto.sh (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 44a22b4..2cf4a8b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,12 @@ -version: 2 +version: 2.1 +parameters: + cmds: + type: string + default: "ssl-vision-client ssl-vision-cli" + jobs: - frontend: + build_node: + resource_class: medium docker: - image: cimg/node:lts steps: @@ -18,99 +24,110 @@ jobs: paths: - frontend/dist/* - backend: + test_go: + resource_class: medium docker: - - image: cimg/go:1.20 + - image: cimg/go:1.20.2 steps: - checkout - attach_workspace: at: . - run: go get -v -t -d ./... - - run: go test -v ./... - - run: - working_directory: cmd/ssl-vision-client - command: | - GOOS=linux GOARCH=amd64 go build -o ../../release/ssl-vision-client_linux_amd64 - GOOS=darwin GOARCH=amd64 go build -o ../../release/ssl-vision-client_darwin_amd64 - GOOS=windows GOARCH=amd64 go build -o ../../release/ssl-vision-client_windows_amd64.exe - - run: - working_directory: cmd/ssl-vision-cli - command: | - GOOS=linux GOARCH=amd64 go build -o ../../release/ssl-vision-cli_linux_amd64 - GOOS=darwin GOARCH=amd64 go build -o ../../release/ssl-vision-cli_darwin_amd64 - GOOS=windows GOARCH=amd64 go build -o ../../release/ssl-vision-cli_windows_amd64.exe + - run: go test -v -covermode=count -coverprofile=count.out ./... + - run: go tool cover -html=count.out -o coverage.html + - store_artifacts: + path: coverage.html + destination: coverage + + build_go: + resource_class: large + docker: + - image: cimg/go:1.20.2 + steps: + - checkout + - attach_workspace: + at: . + - run: go get -v -t -d ./... + - run: | + set -u + version=${CIRCLE_TAG:-} + for cmd in << pipeline.parameters.cmds >>; do + GOOS=linux GOARCH=amd64 go build -o ./release/${cmd}_${version}_linux_amd64 ./cmd/${cmd} + GOOS=linux GOARCH=arm64 go build -o ./release/${cmd}_${version}_linux_arm64 ./cmd/${cmd} + GOOS=linux GOARCH=arm go build -o ./release/${cmd}_${version}_linux_arm ./cmd/${cmd} + GOOS=darwin GOARCH=amd64 go build -o ./release/${cmd}_${version}_darwin_amd64 ./cmd/${cmd} + GOOS=darwin GOARCH=arm64 go build -o ./release/${cmd}_${version}_darwin_arm64 ./cmd/${cmd} + GOOS=windows GOARCH=amd64 go build -o ./release/${cmd}_${version}_windows_amd64.exe ./cmd/${cmd} + done - persist_to_workspace: root: . paths: - release/* - publish-github-release: + publish_gh: + resource_class: small docker: - - image: cimg/go:1.20 + - image: cimg/go:1.20.2 steps: - attach_workspace: at: . - - run: - name: "Prepare artifacts" - working_directory: release - command: | - mkdir gh - mv ssl-vision-client_linux_amd64 gh/ssl-vision-client_${CIRCLE_TAG}_linux_amd64 - mv ssl-vision-client_darwin_amd64 gh/ssl-vision-client_${CIRCLE_TAG}_darwin_amd64 - mv ssl-vision-client_windows_amd64.exe gh/ssl-vision-client_${CIRCLE_TAG}_windows_amd64.exe - mv ssl-vision-cli_linux_amd64 gh/ssl-vision-cli_${CIRCLE_TAG}_linux_amd64 - mv ssl-vision-cli_darwin_amd64 gh/ssl-vision-cli_${CIRCLE_TAG}_darwin_amd64 - mv ssl-vision-cli_windows_amd64.exe gh/ssl-vision-cli_${CIRCLE_TAG}_windows_amd64.exe - - run: - name: "Publish Release on GitHub" - command: | - go install github.com/tcnksm/ghr@v0.16.0 - ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ./release/gh/ + - run: | + set -u + go install github.com/tcnksm/ghr@v0.16.0 + ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete -generatenotes ${CIRCLE_TAG} ./release - docker: + build_docker: + resource_class: small + docker: + - image: cimg/base:2023.04 + steps: + - checkout + - setup_remote_docker: + version: 20.10.18 + - run: | + for cmd in << pipeline.parameters.cmds >>; do + docker build -f ./cmd/${cmd}/Dockerfile -t robocupssl/${cmd}:latest . + done + + publish_docker: + resource_class: small docker: - - image: cimg/base:2023.02 + - image: cimg/base:2023.04 steps: - checkout - setup_remote_docker: version: 20.10.18 - run: | + # Parse version from tag (removing 'v' prefix) TAG=${CIRCLE_TAG:1} TAG=${TAG:-latest} - docker build -t robocupssl/ssl-vision-client:$TAG . - docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}" - docker push robocupssl/ssl-vision-client:$TAG - docker build -t robocupssl/ssl-vision-cli:$TAG . - docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}" - docker push robocupssl/ssl-vision-cli:$TAG + for cmd in << pipeline.parameters.cmds >>; do + docker build -f ./cmd/${cmd}/Dockerfile -t robocupssl/${cmd}:${TAG} . + docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}" + docker push robocupssl/${cmd}:${TAG} + done workflows: version: 2 - main: + build: jobs: - - frontend: - filters: - tags: - only: /.*/ - - backend: - requires: - - frontend - filters: - tags: - only: /.*/ - - publish-github-release: + - build_node + - test_go: + requires: [ build_node ] + release: + jobs: + - build_node: + filters: { branches: { ignore: /.*/ }, tags: { only: /^v.*/ } } + - build_go: + requires: [ build_node ] + filters: { branches: { ignore: /.*/ }, tags: { only: /^v.*/ } } + - publish_gh: context: github - requires: - - backend - filters: - branches: - ignore: /.*/ - tags: - only: /^v.*/ - - docker: + requires: [ build_go ] + filters: { branches: { ignore: /.*/ }, tags: { only: /^v.*/ } } + docker: + jobs: + - build_docker + - publish_docker: context: docker hub - filters: - branches: - only: master - tags: - only: /^v.*/ + filters: { branches: { only: master }, tags: { only: /^v.*/ } } diff --git a/.dockerignore b/.dockerignore index aa195ad..37891a4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,10 @@ -/node_modules -/dist -/.git -/Dockerfile -/.idea -/.vscode \ No newline at end of file +* +!cmd +!frontend +!internal +!pkg +!go.mod +!go.sum + +frontend/node_modules +frontend/dist diff --git a/.editorconfig b/.editorconfig index 9879daf..94e26be 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,10 +7,10 @@ root = true end_of_line = lf insert_final_newline = true indent_style = space +indent_size = 2 + +[*.proto] indent_size = 4 -[*.go] +[Makefile] indent_style = tab - -[*.{vue,yml,json}] -indent_size = 2 diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..7aa8ef7 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,11 @@ +changelog: + categories: + - title: 🏕 Features + labels: + - '*' + exclude: + labels: + - dependencies + - title: 👒 Dependencies + labels: + - dependencies diff --git a/.gitignore b/.gitignore index 185e663..6929a0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,16 @@ .DS_Store node_modules -/dist +/config/ + +# Editor directories and files +.idea/* +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* +!.idea/runConfigurations # local env files .env.local @@ -11,11 +21,11 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw* +# app-specific ignores +/*.json.stream + +# Local installations +/.local + +# Make cache +/.frontend diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0b94869..0000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM node:18-alpine AS build_node -COPY frontend /tmp/ssl-vision-client/frontend -WORKDIR /tmp/ssl-vision-client/frontend -RUN npm install -RUN npm run build - -FROM golang:1.20-alpine AS build_go -WORKDIR /go/src/github.com/RoboCup-SSL/ssl-vision-client -COPY cmd cmd -COPY pkg pkg -COPY frontend/embed.go frontend/embed.go -COPY go.mod . -COPY go.sum . -COPY --from=build_node /tmp/ssl-vision-client/frontend/dist frontend/dist -RUN go install -v ./cmd/ssl-vision-client - -# Start fresh from a smaller image -FROM alpine:3 -COPY --from=build_go /go/bin/ssl-vision-client /app/ssl-vision-client -USER 1000 -EXPOSE 8082 -ENTRYPOINT ["/app/ssl-vision-client"] -CMD [] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c9d8a5f --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +CMDS = ssl-vision-client ssl-vision-cli +DOCKER_TARGETS = $(addprefix docker-, $(CMDS)) +.PHONY: all docker frontend install test run proto $(DOCKER_TARGETS) + +all: install docker + +docker: $(DOCKER_TARGETS) + +$(DOCKER_TARGETS): docker-%: + docker build -f ./cmd/$*/Dockerfile -t $*:latest . + +.frontend: $(shell find frontend/ -type f -not -path "frontend/node_modules/*") + cd frontend && \ + npm install && \ + npm run build && \ + touch ../.frontend + +frontend: .frontend + +install: frontend + go install -v ./... + +test: frontend + go test ./... + +run: frontend + go run ./cmd/$(word 1,$(CMDS)) + +proto: + tools/generateProto.sh diff --git a/README.md b/README.md index 8aa395b..584f947 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,27 @@ By default, the UI is available at http://localhost:8082 ## Development +### Requirements + You need to install following dependencies first: * Go * Node -See [.circleci/config.yml](.circleci/config.yml) for required versions. +See [.circleci/config.yml](.circleci/config.yml) for compatible versions. ### Frontend See [frontend/README.md](frontend/README.md) +### Build + +Build and install all binaries: + +```bash +make install +``` + ### Run Run the backend: @@ -41,8 +51,10 @@ Run the backend: go run cmd/ssl-vision-client/main.go ``` -### Build self-contained release binary +### Update generated protobuf code -```bash -./install.sh +Generate the code for the `.proto` files after you've changed anything in a `.proto` file with: + +```shell +make proto ``` diff --git a/cli.Dockerfile b/cli.Dockerfile deleted file mode 100644 index 165f0b4..0000000 --- a/cli.Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM golang:1.20-alpine AS build -WORKDIR /go/src/github.com/RoboCup-SSL/ssl-vision-client -COPY cmd cmd -COPY pkg pkg -COPY go.mod go.mod -COPY go.sum go.sum -RUN go install -v ./cmd/ssl-vision-cli - -# Start fresh from a smaller image -FROM alpine:3 -COPY --from=build /go/bin/ssl-vision-cli /app/ssl-vision-cli -ENTRYPOINT ["/app/ssl-vision-cli"] -CMD [] diff --git a/cmd/ssl-vision-cli/Dockerfile b/cmd/ssl-vision-cli/Dockerfile new file mode 100644 index 0000000..f923869 --- /dev/null +++ b/cmd/ssl-vision-cli/Dockerfile @@ -0,0 +1,14 @@ +FROM golang:1.20-alpine AS build_go +ARG cmd=ssl-vision-cli +WORKDIR work +COPY . . +RUN go install -v ./cmd/${cmd} + +# Start fresh from a smaller image +FROM alpine:3 +ARG cmd +COPY --from=build_go /go/bin/${cmd} /app/${cmd} +USER 1000 +ENV COMMAND="/app/${cmd}" +ENTRYPOINT "${COMMAND}" +CMD [] diff --git a/cmd/ssl-vision-client/Dockerfile b/cmd/ssl-vision-client/Dockerfile new file mode 100644 index 0000000..017aeeb --- /dev/null +++ b/cmd/ssl-vision-client/Dockerfile @@ -0,0 +1,22 @@ +FROM node:18-alpine AS build_node +COPY frontend frontend +WORKDIR frontend +RUN npm install +RUN npm run build + +FROM golang:1.20-alpine AS build_go +ARG cmd=ssl-vision-client +WORKDIR work +COPY . . +COPY --from=build_node frontend/dist frontend/dist +RUN go install -v ./cmd/${cmd} + +# Start fresh from a smaller image +FROM alpine:3 +ARG cmd +COPY --from=build_go /go/bin/${cmd} /app/${cmd} +RUN mkdir -p config && chown -R 1000: config +USER 1000 +ENV COMMAND="/app/${cmd}" +ENTRYPOINT "${COMMAND}" +CMD [] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f1c797d..3791f88 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,11 +1,11 @@ { - "name": "ssl-vision-client-new", + "name": "ssl-vision-client", "version": "0.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "ssl-vision-client-new", + "name": "ssl-vision-client", "version": "0.0.0", "dependencies": { "vue": "^3.2.45" diff --git a/install.sh b/install.sh deleted file mode 100755 index e41a4d4..0000000 --- a/install.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# frontend -( - cd frontend - npm install - npm run build -) - -# backend -go install -v ./cmd/ssl-vision-client diff --git a/generateProto.sh b/tools/generateProto.sh similarity index 100% rename from generateProto.sh rename to tools/generateProto.sh