From c7fbbabac733ea13609a8000258d7fce02e9e907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= <20689156+shortcuts@users.noreply.github.com> Date: Fri, 17 Dec 2021 11:31:11 +0100 Subject: [PATCH] chore(tooling): clients scripts and Docker image (#43) --- .dockerignore | 7 ++++ .github/actions/cache/action.yml | 2 +- .github/workflows/check.yml | 20 ++++----- Dockerfile | 21 ++++++++++ README.md | 72 +++++++++++++++++++++++++------- openapitools.json | 12 +++--- package.json | 18 ++++---- scripts/build/clients.sh | 42 +++++++++++++++++++ scripts/{ => build}/specs.sh | 8 +++- scripts/docker/build.sh | 9 ++++ scripts/docker/mount.sh | 5 +++ scripts/generate.sh | 11 ++--- scripts/multiplexer.sh | 6 +++ scripts/post-gen/global.sh | 6 +++ scripts/post-gen/java.sh | 44 ++++++++++++++----- scripts/post-gen/javascript.sh | 2 +- 16 files changed, 227 insertions(+), 58 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100755 scripts/build/clients.sh rename scripts/{ => build}/specs.sh (89%) create mode 100755 scripts/docker/build.sh create mode 100755 scripts/docker/mount.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..c09912f552 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.github +.git +.vscode +**/dist +**/build +**/node_modules +playground diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 84f78796dc..c80ad208ff 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -23,7 +23,7 @@ runs: path: '**/node_modules' key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }} - - name: Restore maven dependencies. + - name: Restore maven dependencies uses: actions/cache@v2 with: path: '~/.m2/repository' diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 8cd68ae872..f175c6d256 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -25,16 +25,16 @@ jobs: uses: ./.github/actions/cache - name: Checking search specs - run: yarn specs search + run: yarn build:specs search - name: Checking recommend specs - run: yarn specs recommend + run: yarn build:specs recommend - name: Checking personalization specs - run: yarn specs personalization + run: yarn build:specs personalization - name: Checking analytics specs - run: yarn specs analytics + run: yarn build:specs analytics - name: Lint run: yamllint specs @@ -52,25 +52,25 @@ jobs: run: yarn generate javascript search - name: Build search client - run: yarn client:build-js:search + run: yarn build:clients javascript search - name: Generate recommend client run: yarn generate javascript recommend - name: Build recommend client - run: yarn client:build-js:recommend + run: yarn build:clients javascript recommend - name: Generate personalization client run: yarn generate javascript personalization - name: Build personalization client - run: yarn client:build-js:personalization + run: yarn build:clients javascript personalization - name: Generate analytics client run: yarn generate javascript analytics - name: Build analytics client - run: yarn client:build-js:analytics + run: yarn build:clients javascript analytics - name: Lint run: yarn lint @@ -88,7 +88,7 @@ jobs: run: yarn generate java search - name: Build search client - run: yarn client:build-java + run: yarn build:clients java search cts: runs-on: ubuntu-20.04 @@ -103,7 +103,7 @@ jobs: run: yarn generate - name: Build client - run: yarn client:build + run: yarn build:clients - name: Generate CTS run: yarn cts:generate diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..84b333e327 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +ARG NODE_VERSION=16.13.0 + +FROM node:$NODE_VERSION-alpine + +ENV DOCKER=true + +RUN apk add openjdk11 maven jq bash yamllint perl curl + +WORKDIR /app + +COPY package.json yarn.lock .yarnrc.yml ./ +COPY clients/ ./clients/ +COPY .yarn .yarn +RUN yarn install + +RUN mkdir dist +RUN curl -L "https://github.com/google/google-java-format/releases/download/v1.13.0/google-java-format-1.13.0-all-deps.jar" > dist/google-java-format-1.13.0-all-deps.jar + +COPY . . + +CMD ["bash"] diff --git a/README.md b/README.md index 3b37bc422b..9b5ebfdf77 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,93 @@ -# How to run +# api-clients-automation -## Install and setup env +**Make sure to have Docker installed so you don't have to install the tooling for every API clients.** + +## Setup repository tooling ```bash nvm use && yarn ``` -## Generate clients based on the [`specs`](./specs/) +## Setup dev environment -### All clients +You can also execute docker commands one by one, see [Docker commands](#docker) ```bash -yarn generate +yarn docker:setup ``` -Generic command: +### Docker + +#### Build + +Build docker image from [Dockerfile](./Dockerfile) ```bash -yarn generate +yarn docker:build ``` -### Search client +#### Mount + +Mount docker image on `dev` container ```bash -yarn generate all search +yarn docker:mount ``` -### Recommend client +#### Clean + +Stops `dev` container and clean the built image ```bash -yarn generate all recommend +yarn docker:clean ``` -## Build generated clients +## Contributing + +You can now make changes locally and run commands through the docker container. + +### Generate clients based on the [`specs`](./specs/) + +#### Usage + +```bash +yarn docker generate +``` + +#### Generate all clients ```bash -yarn client:build +yarn docker generate ``` -# Testing clients +### Generate specific client for specific language + +#### Usage + +```bash +yarn docker build:clients +``` + +### Build specific client for specific language + +```bash +yarn docker build:clients java recommend +``` + +## Testing clients The clients can be tested inside the [`playground`](./playground) folder +## Usage + +```bash +yarn docker playground:: +``` + ## JavaScript ```bash -yarn playground:js +yarn docker playground:js:search ``` # Troubleshooting diff --git a/openapitools.json b/openapitools.json index d7b749c8c7..87b241293d 100644 --- a/openapitools.json +++ b/openapitools.json @@ -18,9 +18,9 @@ "modelPropertyNaming": "original", "supportsES6": true, "npmName": "@algolia/client-search", - "packageName": "@algolia/client-search", "npmVersion": "5.0.0", + "packageName": "@algolia/client-search", "isSearchHost": true } }, @@ -39,9 +39,9 @@ "modelPropertyNaming": "original", "supportsES6": true, "npmName": "@algolia/recommend", - "packageName": "@algolia/recommend", "npmVersion": "5.0.0", + "packageName": "@algolia/recommend", "isSearchHost": true } }, @@ -59,9 +59,9 @@ "modelPropertyNaming": "original", "supportsES6": true, "npmName": "@algolia/client-personalization", - "packageName": "@algolia/client-personalization", "npmVersion": "5.0.0", + "packageName": "@algolia/client-personalization", "hasRegionalHost": true, "isPersonalizationHost": true } @@ -80,9 +80,9 @@ "modelPropertyNaming": "original", "supportsES6": true, "npmName": "@algolia/client-analytics", - "packageName": "@algolia/client-analytics", "npmVersion": "5.0.0", + "packageName": "@algolia/client-analytics", "hasRegionalHost": true, "isAnalyticsHost": true } @@ -105,7 +105,9 @@ "additionalProperties": { "sourceFolder": "algoliasearch-core", "java8": true, - "dateLibrary": "java8" + "dateLibrary": "java8", + + "packageName": "algoliasearch-client-java-2" } } } diff --git a/package.json b/package.json index 81981f4d39..e26e18f762 100644 --- a/package.json +++ b/package.json @@ -7,16 +7,17 @@ "tests/" ], "scripts": { + "build:clients": "./scripts/multiplexer.sh ./scripts/build/clients.sh ${0:-all} ${1:-all}", + "build:specs": "./scripts/build/specs.sh ${0:-all} ${1:-yaml}", + "build": "yarn build:specs && yarn build:clients", "clean": "rm -rf **/dist **/build **/node_modules", - "client:build-java": "mvn clean install -f clients/algoliasearch-client-java-2/pom.xml", - "client:build-js:analytics": "yarn workspace @algolia/client-analytics build", - "client:build-js:personalization": "yarn workspace @algolia/client-personalization build", - "client:build-js:recommend": "yarn workspace @algolia/recommend build", - "client:build-js:search": "yarn workspace @algolia/client-search build", - "client:build-js": "yarn client:build-js:search && yarn client:build-js:recommend && yarn client:build-js:personalization && yarn client:build-js:analytics", - "client:build": "yarn client:build-js", "cts:generate": "yarn workspace tests cts:generate", "cts:test": "yarn workspace tests test", + "docker:build": "./scripts/docker/build.sh", + "docker:clean": "docker stop dev; docker rm -f dev; docker image rm -f api-clients-automation", + "docker:mount": "./scripts/docker/mount.sh", + "docker:setup": "yarn docker:clean && yarn docker:build && yarn docker:mount", + "docker": "docker exec dev yarn $*", "lint": "eslint --ext=ts .", "post:generate": "./scripts/post-gen/global.sh", "generate": "./scripts/multiplexer.sh ./scripts/generate.sh ${0:-all} ${1:-all} && yarn post:generate", @@ -25,8 +26,7 @@ "playground:js:personalization": "yarn workspace javascript-playground start:personalization", "playground:js:recommend": "yarn workspace javascript-playground start:recommend", "playground:js:search": "yarn workspace javascript-playground start:search", - "specs:format": "yarn prettier --write specs", - "specs": "./scripts/specs.sh ${0:-all} ${1:-yaml}" + "specs:format": "yarn prettier --write specs" }, "devDependencies": { "@openapitools/openapi-generator-cli": "2.4.18", diff --git a/scripts/build/clients.sh b/scripts/build/clients.sh new file mode 100755 index 0000000000..1d9d3c1bf7 --- /dev/null +++ b/scripts/build/clients.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Break on non-zero code +set -e + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +# Move to the root (easier to locate other scripts) +cd ${DIR}/../.. + +lang=$1 +client=$2 +generator="$lang-$client" +package=$(cat openapitools.json | jq -r --arg generator "$generator" '."generator-cli".generators[$generator].additionalProperties.packageName') + +# Commands are based on the lang +build_client(){ + echo "> Building $generator..." + + if [[ $lang == 'javascript' ]]; then + yarn workspace $package build + elif [[ $lang == 'java' ]]; then + set +e + + log=$(mvn clean install -f clients/$package/pom.xml) + + if [[ $? != 0 ]]; then + echo "$log" + exit 1 + fi + + set -e + fi +} + + + +if [[ -z $package ]]; then + echo "Unknown package ${package}" + exit 1 +fi + +build_client diff --git a/scripts/specs.sh b/scripts/build/specs.sh similarity index 89% rename from scripts/specs.sh rename to scripts/build/specs.sh index 90089a5369..9b14d422f9 100755 --- a/scripts/specs.sh +++ b/scripts/build/specs.sh @@ -1,5 +1,11 @@ #!/bin/bash +if [[ ! $CI ]] && [[ ! $DOCKER ]]; then + echo "You should run scripts via the docker container, see README.md" + + exit 1 +fi + # Break on non-zero code set -e @@ -10,7 +16,7 @@ SPECS=() DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" # Move to the root (easier to locate other scripts) -cd ${DIR}/.. +cd ${DIR}/../.. find_specs() { echo "> Searching for available specs..." diff --git a/scripts/docker/build.sh b/scripts/docker/build.sh new file mode 100755 index 0000000000..2206dea33e --- /dev/null +++ b/scripts/docker/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)/../.." + +cd $ROOT + +NODE_VERSION=$(cat .nvmrc) + +docker build --build-arg NODE_VERSION=$NODE_VERSION -t api-clients-automation . diff --git a/scripts/docker/mount.sh b/scripts/docker/mount.sh new file mode 100755 index 0000000000..d6fa76e1eb --- /dev/null +++ b/scripts/docker/mount.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)/../.." + +docker run -d -it --name dev --mount type=bind,source=$ROOT/,target=/app api-clients-automation diff --git a/scripts/generate.sh b/scripts/generate.sh index e0dc6bfdf6..6468568931 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -9,13 +9,14 @@ cd ${DIR}/.. lang=$1 client=$2 +generator="$1-$2" # Run the pre generation script if it exists. run_pre_gen() { pregen="./scripts/pre-gen/${lang}.sh" if [[ -f "$pregen" ]]; then - echo "> Running pre-gen script for ${lang}-${client}..." + echo "> Running pre-gen script for $generator..." $pregen $client fi } @@ -23,9 +24,9 @@ run_pre_gen() { generate_client() { set +e - echo "> Generating code for ${lang}-${client}..." + echo "> Generating code for $generator..." - log=$(yarn openapi-generator-cli generate --generator-key "${lang}-${client}") + log=$(yarn openapi-generator-cli generate --generator-key "$generator") if [[ $? != 0 ]]; then echo "$log" @@ -40,8 +41,8 @@ run_post_gen() { postgen="./scripts/post-gen/${lang}.sh" if [[ -f "$postgen" ]]; then - echo "> Running post-gen script for ${lang}-${client}..." - $postgen "${lang}-${client}" + echo "> Running post-gen script for $generator..." + $postgen "$generator" fi } diff --git a/scripts/multiplexer.sh b/scripts/multiplexer.sh index 576f049e6c..3aefc643b6 100755 --- a/scripts/multiplexer.sh +++ b/scripts/multiplexer.sh @@ -2,6 +2,12 @@ # Call this script with multiplexer.sh # to run the cmd for all the required lang-client combination +if [[ ! $CI ]] && [[ ! $DOCKER ]]; then + echo "You should run scripts via the docker container, see README.md" + + exit 1 +fi + # Break on non-zero code set -e diff --git a/scripts/post-gen/global.sh b/scripts/post-gen/global.sh index 13b1859bf9..99e62dcde7 100755 --- a/scripts/post-gen/global.sh +++ b/scripts/post-gen/global.sh @@ -4,6 +4,12 @@ if [[ $CI ]]; then exit 0 fi +if [[ ! $DOCKER ]]; then + echo "You should run scripts via the docker container, see README.md" + + exit 1 +fi + format_specs() { set +e diff --git a/scripts/post-gen/java.sh b/scripts/post-gen/java.sh index 8b3bc1dbed..8e9ca2968d 100755 --- a/scripts/post-gen/java.sh +++ b/scripts/post-gen/java.sh @@ -6,19 +6,41 @@ export CLIENT=$(cat openapitools.json | jq -r --arg generator "$GENERATOR" '."ge # Restore the oneOf spec mv ./specs/search/paths/search/search.yml.bak ./specs/search/paths/search/search.yml -# Replace {} (Openapi default) with new Object -find $CLIENT -type f -name "*.java" | xargs sed -i '' -e 's/= {}/= new Object()/g' +# Replace {} (OpenAPI default) with new Object +find "$CLIENT" -type f -name "*.java" | xargs sed -i -e 's~= {}~= new Object()~g' # Create a special class for the OneOf integer string (not complete yet, juste here for compilation) echo "package com.algolia.model;public class OneOfintegerstring {}" > $CLIENT/algoliasearch-core/com/algolia/model/OneOfintegerstring.java -# Download the formatter if not present and run it -javaFormatter="google-java-format-1.13.0-all-deps.jar" -if [[ ! -f "dist/$javaFormatter" ]]; then - echo "Downloading formatter dependency" - mkdir dist - curl -L "https://github.com/google/google-java-format/releases/download/v1.13.0/$javaFormatter" > dist/$javaFormatter -fi -find $CLIENT -type f -name "*.java" | xargs java -jar dist/$javaFormatter -r +format_client() { + set +e -yarn prettier --write $CLIENT/**/*.java + echo "> Formatting $GENERATOR..." + + # Download the formatter if not present and run it + javaFormatter="google-java-format-1.13.0-all-deps.jar" + + if [[ ! -f "dist/$javaFormatter" ]]; then + echo "Downloading formatter dependency" + mkdir dist + curl -L "https://github.com/google/google-java-format/releases/download/v1.13.0/$javaFormatter" > dist/$javaFormatter + fi + + find $CLIENT -type f -name "*.java" | xargs java --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -jar dist/$javaFormatter -r + + log=$(yarn prettier --write $CLIENT/**/*.java) + + if [[ $? != 0 ]]; then + echo "$log" + exit 1 + fi + + set -e +} + +format_client diff --git a/scripts/post-gen/javascript.sh b/scripts/post-gen/javascript.sh index e96e6d07b8..b3403697a1 100755 --- a/scripts/post-gen/javascript.sh +++ b/scripts/post-gen/javascript.sh @@ -6,7 +6,7 @@ export CLIENT=$(cat openapitools.json | jq -r --arg generator "$GENERATOR" '."ge echo "> Exporting utils for ${GENERATOR}..." mkdir -p $CLIENT/utils -cp -R clients/algoliasearch-client-javascript/utils/ $CLIENT/utils +cp -R clients/algoliasearch-client-javascript/utils/ $CLIENT/ lint_client() { set +e