diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8f9faf5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +.git/ +docs/ +cache/ +bin/ +var/ +lib/ +include/ +share/ +develop-eggs/ +parts/ +.installed.cfg +.mr.developer.cfg +src/collective/taxonomy/javascripts/node_modules/ +src/collective/taxonomy/javascripts/cypress/videos/ +src/collective/taxonomy/javascripts/cypress/screenshots/ diff --git a/.gitignore b/.gitignore index 1c87c6e..0f4b60e 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ share/ include/ lib/ share/ +cache/ +src/collective/taxonomy/javascripts/cypress/videos/ +src/collective/taxonomy/javascripts/cypress/screenshots/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2f56b0f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# Plone + make + virtualenv +FROM plone:5.2.1 +ARG DEBIAN_FRONTEND=noninteractive + +COPY . /plone/app + +RUN apt-get update -qy \ + && apt-get install -qy \ + make \ + && pip install -q virtualenv==16.7.9 \ + && mkdir /plone/.buildout \ + && echo "[buildout]" > /plone/.buildout/default.cfg \ + && echo "download-cache = /app/cache/downloads" >> /plone/.buildout/default.cfg \ + && echo "eggs-directory = /app/cache/eggs" >> /plone/.buildout/default.cfg \ + && mkdir /app \ + && ln -sf /plone/buildout-cache /app/cache \ + && usermod -u 1000 plone \ + && groupmod -g 1000 plone \ + && chown -R plone:plone /plone \ + && chown -R plone:plone /app \ + && su - plone -c 'cd /plone/app && make build-backend' \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /plone/buildout-cache/downloads/* + +USER plone +VOLUME /app +WORKDIR /plone/app +ENTRYPOINT ["/usr/bin/make"] +CMD ["start-backend"] diff --git a/Makefile b/Makefile index 165e31c..1d40225 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ SHELL := /bin/bash # Run test if not on Travis or Python 3 and Plone 5.2 NOT_TRAVIS_OR_PYTHON3_PLONE52 := $(shell if [ -z "$$TRAVIS" ] || ([ "$$PLONE_VERSION" == "5.2" ] && [ "$$TRAVIS_PYTHON_VERSION" == "3.7" ]); then echo "true"; else echo "false"; fi) +VIRTUALENV_NOT_INSTALLED := $(shell if [ ! -d bin ]); then echo "true"; else echo "false"; fi) version = 3 @@ -31,6 +32,7 @@ build-backend: ./venv/bin/buildout bootstrap ifeq ("$(NOT_TRAVIS_OR_PYTHON3_PLONE52)", "true") ./venv/bin/pip install black +endif endif bin/buildout @@ -46,12 +48,15 @@ start: ## Start split-window -h "make start-frontend" \; \ select-pane -t 0; \ else \ - make start-backend; \ + make start-backend-development; \ fi start-backend: @echo "$(GREEN)==> Start Plone Backend$(RESET)" - NODE_ENV=development bin/instance fg + bin/instance fg + +start-backend-development: + NODE_ENV=development make start-backend start-frontend: @echo "$(GREEN)==> Start Webpack Watcher$(RESET)" @@ -64,38 +69,35 @@ start-cypress: ## Start Cypress cd src/collective/taxonomy/javascripts && yarn run cypress open bin/instance stop -.PHONY: Test -test: code-format-check code-analysis test-backend test-frontend test-cypress ## Test - .PHONY: Code Format Check -code-format-check: code-format-check-backend code-format-check-frontend ## Code Format Check +lint: lint-backend lint-frontend ## Code Format Check -code-format-check-backend: +lint-backend: @echo "$(GREEN)==> Run Python code format check$(RESET)" ifeq ("$(NOT_TRAVIS_OR_PYTHON3_PLONE52)", "true") ./venv/bin/black --check src/ + ./venv/bin/code-analysis endif -code-format-check-frontend: +lint-frontend: @echo "$(GREEN)==> Run Javascript code format check$(RESET)" cd src/collective/taxonomy/javascripts && yarn prettier -.PHONY: Code Format -code-format: code-format-backend code-format-frontend ## Code Format +.PHONY: Code Format Fixes +lint-fix: lint-fix-backend lint-fix-frontend ## Code Format Fixes -code-format-backend: +lint-fix-backend: @echo "$(GREEN)==> Run Python code format$(RESET)" +ifeq ("$(NOT_TRAVIS_OR_PYTHON3_PLONE52)", "true") ./venv/bin/black src/ +endif -code-format-frontend: - @echo "$(GREEN)==> Run Javascript code format$(RESET)" +lint-fix-frontend: + @echo "$(GREEN)==> Run Javascript code format fix$(RESET)" cd src/collective/taxonomy/javascripts && yarn prettier:fix -code-analysis: - @echo "$(green)==> Run static code analysis$(reset)" -ifeq ("$(NOT_TRAVIS_OR_PYTHON3_PLONE52)", "true") - bin/code-analysis -endif +.PHONY: Test +test: lint test-backend test-frontend test-cypress ## Test test-backend: @echo "$(GREEN)==> Run Backend Tests$(RESET)" @@ -122,6 +124,9 @@ test-cypress-foreground: .PHONY: Clean clean: ## Clean @echo "$(RED)==> Cleaning environment and build$(RESET)" - git clean -Xdf + rm -rf bin lib include share develop-eggs parts .installed.cfg .mr.developer.cfg + cd src/collective/taxonomy/javascripts && rm -rf node_modules yarn* + +include Makefile.docker .PHONY: all clean diff --git a/Makefile.docker b/Makefile.docker new file mode 100644 index 0000000..c6e216d --- /dev/null +++ b/Makefile.docker @@ -0,0 +1,85 @@ +NAME='collective/collective.taxonomy:2.0.1' + +.PHONY: Build with Docker +docker-build: docker-build-backend docker-build-frontend ## Build with Docker + +docker-build-backend: + @echo "$(GREEN)==> Setup Build with Docker$(RESET)" + if [[ "$$(docker images -q $(NAME) 2> /dev/null)" == "" ]]; then \ + docker build -t $(NAME) . ; \ + fi + if [ ! -d cache ]; then \ + mkdir -p cache/eggs cache/downloads/list cache/extends; \ + docker-compose run --rm backend "cd /app/cache/eggs && find /plone/buildout-cache/eggs/* -maxdepth 0 -type d -exec ln -sf {} . \;" || true ; \ + fi + docker-compose run --rm backend "make build-backend" + +build-frontend-docker: + @echo "$(GREEN)==> Build Frontend$(RESET)" + cd src/collective/taxonomy/javascripts && yarn --network-timeout 30000 + cd src/collective/taxonomy/javascripts && yarn build + +docker-build-frontend: + @echo "$(GREEN)==> Build Frontend with Docker$(RESET)" + mkdir -p cache/npm cache/yarn cache/cypress + docker-compose run --rm frontend "make build-frontend-docker" + +.PHONY: Start with Docker +docker-start: ## Start with Docker + @echo "$(GREEN)==> Start Plone and Webpack watcher with Docker$(RESET)" + docker-compose up + +.PHONY: Code Format Check with Docker +docker-lint: docker-lint-backend docker-lint-frontend ## Code Format Check with Docker + +docker-lint-backend: + @echo "$(GREEN)==> Run Python code format check with Docker$(RESET)" + docker-compose run --rm backend "make lint-backend" + +docker-lint-frontend: + @echo "$(GREEN)==> Run Javascript code format check with Docker$(RESET)" + docker-compose run --rm frontend "make lint-frontend" + +.PHONY: Code Format Fixes with Docker +docker-lint-fix: docker-lint-fix-backend docker-lint-fix-frontend ## Code Format Fixes with Docker + +docker-lint-fix-backend: + @echo "$(GREEN)==> Run Python code format fix with Docker$(RESET)" + docker-compose run --rm backend "make lint-fix-backend" + +docker-lint-fix-frontend: + @echo "$(GREEN)==> Run Javascript code format fix with Docker$(RESET)" + docker-compose run --rm frontend "make lint-fix-frontend" + +.PHONY: Test +docker-test: docker-lint docker-test-backend docker-test-frontend docker-test-cypress ## Test + +docker-test-backend: + @echo "$(GREEN)==> Run Backend Tests with Docker$(RESET)" + docker-compose run --rm backend "make test-backend" + +docker-test-frontend: + @echo "$(GREEN)==> Run Frontend Tests with Docker$(RESET)" + docker-compose run --rm frontend "make test-frontend" + +test-cypress-docker: + while ! curl -sf http://frontend:3000 > /dev/null; do sleep 1; done + while ! curl -sf http://backend:8080/Plone > /dev/null; do sleep 1; done + cd src/collective/taxonomy/javascripts && yarn run cypress run + +docker-test-cypress: + @echo "$(GREEN)==> Run Cypress Test with Docker$(RESET)" + docker-compose up -d + docker-compose exec frontend make test-cypress-docker + docker-compose down + +docker-clean-image: + if [[ "$$(docker images -q $(NAME) 2> /dev/null)" != "" ]]; then \ + docker image rm $(NAME) ; \ + fi + +docker-clean: + @echo "$(RED)==> Cleaning Docker environment$(RESET)" + rm -rf cache + docker-compose down + make clean diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d6fa406 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: '2' +services: + frontend: + image: cypress/base:12.18.0 + user: 1000:1000 + ports: + - 3000:3000 + volumes: + - .:/app + environment: + - npm_config_cache=/app/cache/npm + - npm_config_global=true + - YARN_CACHE_FOLDER=/app/cache/yarn + - CYPRESS_CACHE_FOLDER=/app/cache/cypress + - CYPRESS_VIDEO=false + - CYPRESS_baseUrl=http://backend:8080/Plone + working_dir: /app + entrypoint: /bin/sh -c + command: + - make start-frontend + backend: + image: collective/collective.taxonomy:2.0.1 + user: 1000:1000 + ports: + - 8080:8080 + volumes: + - .:/app + working_dir: /app + entrypoint: /bin/sh -c + command: + - make start-backend-development diff --git a/src/collective/taxonomy/javascripts/server.js b/src/collective/taxonomy/javascripts/server.js index dcc2a9d..f8398a0 100644 --- a/src/collective/taxonomy/javascripts/server.js +++ b/src/collective/taxonomy/javascripts/server.js @@ -17,11 +17,11 @@ app.get('*', function(req, res) { res.sendFile(path.join(__dirname, 'index.html')) }) -app.listen(3000, 'localhost', function (err) { +app.listen(3000, '0.0.0.0', function (err) { if (err) { console.log(err) return } - console.log('Listening at http://localhost:3000') + console.log('Listening at http://0.0.0.0:3000') })