Skip to content

Commit

Permalink
Improvements from moving sneridagh.dev to the new setup (#20)
Browse files Browse the repository at this point in the history
* knowledge from moving sneridagh.dev to the new setup

* Better now

* Try to fix tests

* Finally

* Fix Readme RST in backend
  • Loading branch information
sneridagh authored May 21, 2024
1 parent d9c61b3 commit 9d2da16
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 79 deletions.
3 changes: 1 addition & 2 deletions backend_addon/{{ cookiecutter.__folder_name }}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

This package contains a simple volto configuration.

Installation
------------
## Installation

Install {{ cookiecutter.python_package_name }} with `pip`:

Expand Down
4 changes: 4 additions & 0 deletions project/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"1",
"0"
],
"__npm_package_name": "{{ cookiecutter.frontend_addon_name }}",
"__folder_name": "{{ cookiecutter.project_slug }}",
"__python_package_name_upper": "{{ cookiecutter.python_package_name | pascal_case }}",
"__node_version": "{{ cookiecutter.volto_version | node_version_for_volto }}",
Expand All @@ -51,6 +52,9 @@
"__pre_commit_version": "3.7.1",
"__gha_enable": true,
"__gha_version_checkout": "v4",
"__gha_version_setup_node": "v4",
"__gha_version_setup_pnpm": "v4",
"__gha_version_cache": "v4",
"__gha_version_docker_stack": "v1.2.0",
"__gha_version_code_analysis": "v2",
"__gha_version_docker_metadata": "v5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,68 @@ defaults:
working-directory: ./frontend

jobs:
meta:
runs-on: ubuntu-latest
outputs:
BASE_TAG: {{"${{ steps.vars.outputs.BASE_TAG }}"}}
VOLTO_VERSION: {{"${{ steps.vars.outputs.VOLTO_VERSION }}"}}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Compute several vars needed for the build
id: vars
run: |
echo 'BASE_TAG=sha-$(git rev-parse --short HEAD)' >> $GITHUB_OUTPUT
python3 -c 'import json; data = json.load(open("./mrs.developer.json")); print("VOLTO_VERSION=" + data["core"]["tag"])' >> $GITHUB_OUTPUT
- name: Test vars
run: |
echo 'BASE_TAG={{"${{ steps.vars.outputs.BASE_TAG }}"}}'
echo 'VOLTO_VERSION={{"${{ steps.vars.outputs.VOLTO_VERSION }}"}}'
code-analysis:
runs-on: ubuntu-latest
steps:
- name: Checkout codebase
uses: actions/checkout@{{ cookiecutter.__gha_version_checkout }}

- name: Update Global Yarn
run: |
corepack enable
corepack prepare yarn@stable --activate
- name: Use Node.js {{ "${{ env.node-version }}" }}
uses: actions/setup-node@v3
uses: actions/setup-node@{{ cookiecutter.__gha_version_setup_node }}
with:
node-version: {{ "${{ env.NODE_VERSION }}" }}
cache: 'yarn'
cache-dependency-path: 'frontend/yarn.lock'

- name: Prettier
id: prettier
run: npx [email protected] --single-quote --check 'src/**/*.{js,jsx,ts,tsx,css,scss}' --config=package.json
- uses: pnpm/action-setup@{{ cookiecutter.__gha_version_setup_pnpm }}
name: Install pnpm
with:
version: 9
# We don't want to install until later,
# when the cache is in place
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Install packages
- uses: actions/cache@{{ cookiecutter.__gha_version_cache }}
name: Setup pnpm cache
with:
path: {{"${{ env.STORE_PATH }}"}}
key: {{"${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}"}}
restore-keys: |
{{"${{ runner.os }}"}}-pnpm-store-
- name: Install dependencies
run: make install

- name: ESLint
id: eslint
- name: Linting
id: lint
if: {{ "${{ success() || failure() }}" }}
run: yarn run lint:ci
run: make lint

- name: i18n sync
id: i18n
if: {{ "${{ success() || failure() }}" }}
run: make i18n-ci
run: make ci-i18n

- name: Unit Tests
id: unit
Expand All @@ -64,15 +91,14 @@ jobs:
echo '# Code Analysis' >> $GITHUB_STEP_SUMMARY
echo '| Test | Status |' >> $GITHUB_STEP_SUMMARY
echo '| --- | --- |' >> $GITHUB_STEP_SUMMARY
{{ "echo '| Prettier | ${{ steps.prettier.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY" }}
{{ "echo '| ESLint | ${{ steps.eslint.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY" }}
{{ "echo '| Lint | ${{ steps.lint.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY" }}
{{ "echo '| i18n | ${{ steps.i18n.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY" }}
{{ "echo '| Unit Tests | ${{ steps.unit.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY " }}
release:
runs-on: ubuntu-latest
needs:
- meta
- code-analysis
permissions:
contents: read
Expand Down Expand Up @@ -125,4 +151,6 @@ jobs:
file: frontend/Dockerfile
push: {{"${{ github.event_name != 'pull_request' }}"}}
tags: {{"${{ steps.meta.outputs.tags }}"}}
labels: ${{"${{ steps.meta.outputs.labels }}"}}
labels: {{"${{ steps.meta.outputs.labels }}"}}
build-args: |
VOLTO_VERSION={{"${{ needs.meta.outputs.VOLTO_VERSION }}"}}
7 changes: 5 additions & 2 deletions sub/project_settings/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
"language_code": "en",
"volto_version": "{{ 'Yes' | latest_volto }}",
"github_organization": "collective",
"container_registry": ["github", "docker_hub", "gitlab"],
"__npm_package_name": "{{ cookiecutter.frontend_addon_name }}",
"__container_registry_prefix": "{{ cookiecutter.container_registry | image_prefix }}",
"__container_image_prefix": "{{ cookiecutter.__container_registry_prefix }}{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}",
"__folder_name": "{{ cookiecutter.project_slug }}",
"__package_name": "{{ cookiecutter.python_package_name | package_name }}",
"__package_namespace": "{{ cookiecutter.python_package_name | package_namespace }}",
Expand All @@ -17,8 +21,7 @@
"__profile_language": "{{ cookiecutter.language_code|gs_language_code }}",
"__locales_language": "{{ cookiecutter.language_code|locales_language_code }}",
"__node_version": "{{ cookiecutter.volto_version | node_version_for_volto }}",
"_copy_without_render": [
],
"_copy_without_render": [],
"_extensions": [
"cookieplone.filters.use_prerelease_versions",
"cookieplone.filters.node_version_for_volto",
Expand Down
1 change: 1 addition & 0 deletions sub/project_settings/tests/test_cutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result
"backend/src/project/title/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml",
"frontend/.dockerignore",
"frontend/Dockerfile",
"frontend/Makefile",
"frontend/packages/volto-project-title/src/index.js",
],
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
.yarn/cache
*.log
build
cache
cypress
Dockerfile
node_modules
omelette
Original file line number Diff line number Diff line change
@@ -1,62 +1,30 @@
# syntax=docker/dockerfile:1
FROM node:{{ cookiecutter.__node_version }}-slim as base
FROM base as builder

RUN <<EOT
set -e
apt update
apt install -y --no-install-recommends python3 build-essential
mkdir /app
chown -R node:node /app
rm -rf /var/lib/apt/lists/*
EOT

COPY --chown=node . /build/
RUN corepack enable

USER node
WORKDIR /build
RUN <<EOT
set -e
make install
yarn build
ARG VOLTO_VERSION
# TODO: Replace with
# FROM plone/frontend-builder:${VOLTO_VERSION}
# when the main image is ready
FROM ghcr.io/kitconcept/frontend-builder:${VOLTO_VERSION} as builder

COPY --chown=node packages/volto-sneridagh-dev /app/packages/volto-sneridagh-dev
COPY --chown=node volto.config.js /app/
COPY --chown=node package.json /app/package.json.temp

RUN --mount=type=cache,id=pnpm,target=/app/.pnpm-store,uid=1000 <<EOT
python3 -c "import json; data = json.load(open('package.json.temp')); deps = data['dependencies']; data['dependencies'].update(deps); json.dump(data, open('package.json', 'w'), indent=2)"
rm package.json.temp
pnpm install
pnpm build
pnpm install --prod
EOT

FROM base
# TODO: Replace with
# FROM plone/frontend-prod-config:${VOLTO_VERSION}
# when the main image is ready
FROM ghcr.io/kitconcept/frontend-prod-config:${VOLTO_VERSION}

LABEL maintainer="{{ cookiecutter.author }} <{{ cookiecutter.email }}>" \
org.label-schema.name="{{ cookiecutter.project_slug }}-frontend" \
org.label-schema.description="{{ cookiecutter.title }} frontend image." \
org.label-schema.vendor="{{ cookiecutter.author }}"

# Install busybox and wget
RUN <<EOT
set -e
apt update
apt install -y --no-install-recommends busybox wget
busybox --install -s
rm -rf /var/lib/apt/lists/*
mkdir /app
chown -R node:node /app
EOT

# Run the image with user node
USER node

# Copy
COPY --from=builder /build/ /app/

# Set working directory to /app
WORKDIR /app

# Expose default Express port
EXPOSE 3000

# Set healthcheck to port 3000
HEALTHCHECK --interval=10s --timeout=5s --start-period=30s CMD [ -n "$LISTEN_PORT" ] || LISTEN_PORT=3000 ; wget -q http://127.0.0.1:"$LISTEN_PORT" -O - || exit 1

# Entrypoint would be yarn
ENTRYPOINT [ "yarn" ]

# And the image will run in production mode
CMD ["start:prod"]
COPY --from=builder /app/ /app/
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
### Defensive settings for make:
# https://tech.davis-hansson.com/p/make/
SHELL:=bash
.ONESHELL:
.SHELLFLAGS:=-eu -o pipefail -c
.SILENT:
.DELETE_ON_ERROR:
MAKEFLAGS+=--warn-undefined-variables
MAKEFLAGS+=--no-builtin-rules

CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

# Recipe snippets for reuse

# We like colors
# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects
RED=`tput setaf 1`
GREEN=`tput setaf 2`
RESET=`tput sgr0`
YELLOW=`tput setaf 3`

PLONE_VERSION=6
DOCKER_IMAGE=plone/server-dev:${PLONE_VERSION}
DOCKER_IMAGE_ACCEPTANCE=plone/server-acceptance:${PLONE_VERSION}

ADDON_NAME='{{ cookiecutter.__npm_package_name }}'
IMAGE_NAME={{cookiecutter.__container_image_prefix}}-frontend
IMAGE_TAG=latest
VOLTO_VERSION = $(shell cat ./mrs.developer.json | python -c "import sys, json; print(json.load(sys.stdin)['core']['tag'])")

.PHONY: help
help: ## Show this help
@echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"

# Dev Helpers

.PHONY: install
install: ## Installs the add-on in a development environment
pnpm dlx mrs-developer missdev --no-config --fetch-https
pnpm i

.PHONY: start
start: ## Starts Volto, allowing reloading of the add-on during development
pnpm start

.PHONY: build
build: ## Build a production bundle for distribution of the project with the add-on
pnpm build

.PHONY: i18n
i18n: ## Sync i18n
pnpm --filter $(ADDON_NAME) i18n

.PHONY: format
format: ## Format codebase
pnpm lint:fix
pnpm prettier:fix
pnpm stylelint:fix

.PHONY: lint
lint: ## Lint, or catch and remove problems, in code base
pnpm lint
pnpm prettier
pnpm stylelint

.PHONY: release
release: ## Release the add-on on npmjs.org
pnpm release

.PHONY: release-dry-run
release-dry-run: ## Dry-run the release of the add-on on npmjs.org
pnpm release

.PHONY: test
test: ## Run unit tests
pnpm test

.PHONY: test-ci
ci-test: ## Run unit tests in CI
CI=1 RAZZLE_JEST_CONFIG=$(CURRENT_DIR)/jest-addon.config.js pnpm --filter @plone/volto test -- --passWithNoTests

.PHONY: backend-docker-start
backend-docker-start: ## Starts a Docker-based backend for development
@echo "$(GREEN)==> Start Docker-based Plone Backend$(RESET)"
docker run -it --rm --name=backend -p 8080:8080 -e SITE=Plone $(DOCKER_IMAGE)

## Storybook
.PHONY: storybook-start
storybook-start: ## Start Storybook server on port 6006
@echo "$(GREEN)==> Start Storybook$(RESET)"
pnpm run storybook

.PHONY: storybook-build
storybook-build: ## Build Storybook
@echo "$(GREEN)==> Build Storybook$(RESET)"
mkdir -p $(CURRENT_DIR)/.storybook-build
pnpm run build-storybook -o $(CURRENT_DIR)/.storybook-build

## Acceptance
.PHONY: acceptance-frontend-dev-start
acceptance-frontend-dev-start: ## Start acceptance frontend in development mode
RAZZLE_API_PATH=http://127.0.0.1:55001/plone pnpm start

.PHONY: acceptance-frontend-prod-start
acceptance-frontend-prod-start: ## Start acceptance frontend in production mode
RAZZLE_API_PATH=http://127.0.0.1:55001/plone pnpm build && pnpm start:prod

.PHONY: acceptance-backend-start
acceptance-backend-start: ## Start backend acceptance server
docker run -it --rm -p 55001:55001 $(DOCKER_IMAGE_ACCEPTANCE)

.PHONY: ci-acceptance-backend-start
ci-acceptance-backend-start: ## Start backend acceptance server in headless mode for CI
docker run -i --rm -p 55001:55001 $(DOCKER_IMAGE_ACCEPTANCE)

.PHONY: acceptance-test
acceptance-test: ## Start Cypress in interactive mode
pnpm --filter @plone/volto exec cypress open --config-file $(CURRENT_DIR)/cypress.config.js --config specPattern=$(CURRENT_DIR)'/cypress/tests/**/*.{js,jsx,ts,tsx}'

.PHONY: ci-acceptance-test
ci-acceptance-test: ## Run cypress tests in headless mode for CI
pnpm --filter @plone/volto exec cypress run --config-file $(CURRENT_DIR)/cypress.config.js --config specPattern=$(CURRENT_DIR)'/cypress/tests/**/*.{js,jsx,ts,tsx}'

.PHONY: build-image
build-image: ## Build Docker Image
@DOCKER_BUILDKIT=1 docker build . -t $(IMAGE_NAME):$(IMAGE_TAG) -f Dockerfile --build-arg VOLTO_VERSION=$(VOLTO_VERSION)

0 comments on commit 9d2da16

Please sign in to comment.