Makefile 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #
  2. # Copyright 2018-2022 Elyra Authors
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. .PHONY: help purge uninstall-src uninstall clean
  17. .PHONY: lint-dependencies lint-server black-format prettier-check-ui eslint-check-ui prettier-ui eslint-ui lint-ui lint
  18. .PHONY: dev-link dev-unlink
  19. .PHONY: build-dependencies dev-dependencies yarn-install build-ui package-ui package-ui-dev
  20. .PHONY: build-server install-server-package install-server
  21. .PHONY: install install-all install-dev install-examples install-gitlab-dependency check-install watch release
  22. .PHONY: test-dependencies pytest test-server test-ui-unit test-integration test-integration-debug test-ui test
  23. .PHONY: docs-dependencies docs
  24. .PHONY: elyra-image elyra-image-env publish-elyra-image kf-notebook-image publish-kf-notebook-image
  25. .PHONY: container-images publish-container-images validate-runtime-image validate-runtime-images
  26. SHELL:=/bin/bash
  27. # Container execs
  28. CONTAINER_EXEC=docker
  29. # Python execs
  30. PYTHON?=python
  31. PYTHON_PIP=$(PYTHON) -m pip
  32. PYTHON_VERSION?=3.8
  33. CONDA_ACTIVATE = source $$(conda info --base)/etc/profile.d/conda.sh ; conda activate
  34. ELYRA_VERSION:=$$(grep __version__ elyra/_version.py | cut -d"\"" -f2)
  35. TAG:=dev
  36. IMAGE_IS_LATEST=False
  37. ELYRA_IMAGE=elyra/elyra:$(TAG)
  38. ELYRA_IMAGE_LATEST=elyra/elyra:latest
  39. ELYRA_IMAGE_ENV?=elyra-image-env
  40. KF_NOTEBOOK_IMAGE=elyra/kf-notebook:$(TAG)
  41. KF_NOTEBOOK_IMAGE_LATEST=elyra/kf-notebook:latest
  42. # Contains the set of commands required to be used by elyra
  43. REQUIRED_RUNTIME_IMAGE_COMMANDS?="curl python3"
  44. REMOVE_RUNTIME_IMAGE?=0 # Invoke `make REMOVE_RUNTIME_IMAGE=1 validate-runtime-images` to have images removed after validation
  45. UPGRADE_STRATEGY?=only-if-needed
  46. # Black CMD for code formatting
  47. BLACK_CMD:=$(PYTHON) -m black --check --diff --color .
  48. help:
  49. # http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
  50. @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
  51. ## Clean targets
  52. purge:
  53. rm -rf build *.egg-info yarn-error.log
  54. rm -rf node_modules lib dist
  55. rm -rf $$(find packages -name node_modules -type d -maxdepth 2)
  56. rm -rf $$(find packages -name dist -type d)
  57. rm -rf $$(find packages -name lib -type d)
  58. rm -rf $$(find packages -name *.egg-info -type d)
  59. rm -rf $$(find . -name __pycache__ -type d)
  60. rm -rf $$(find . -name tsconfig.tsbuildinfo)
  61. rm -rf $$(find . -name package-lock.json)
  62. rm -rf $$(find . -name .pytest_cache)
  63. rm -rf $(yarn cache dir)
  64. uninstall-src: # Uninstalls source extensions if they're still installed
  65. - jupyter labextension unlink --no-build @elyra/services
  66. - jupyter labextension unlink --no-build @elyra/ui-components
  67. - jupyter labextension unlink --no-build @elyra/metadata-common
  68. - jupyter labextension unlink --no-build @elyra/script-editor
  69. - jupyter labextension uninstall --no-build @elyra/theme-extension
  70. - jupyter labextension uninstall --no-build @elyra/code-snippet-extension
  71. - jupyter labextension uninstall --no-build @elyra/metadata-extension
  72. - jupyter labextension uninstall --no-build @elyra/pipeline-editor-extension
  73. - jupyter labextension uninstall --no-build @elyra/python-editor-extension
  74. - jupyter labextension uninstall --no-build @elyra/r-editor-extension
  75. - jupyter labextension uninstall --no-build @elyra/scala-editor-extension
  76. - jupyter labextension uninstall --no-build @elyra/code-viewer-extension
  77. - jupyter labextension uninstall --no-build @elyra/script-debugger-extension
  78. - jupyter labextension unlink --no-build @elyra/pipeline-services
  79. - jupyter labextension unlink --no-build @elyra/pipeline-editor
  80. uninstall: uninstall-src
  81. $(PYTHON_PIP) uninstall -y jupyterlab-git
  82. $(PYTHON_PIP) uninstall -y nbdime
  83. $(PYTHON_PIP) uninstall -y jupyter-lsp
  84. - jupyter labextension uninstall @krassowski/jupyterlab-lsp
  85. $(PYTHON_PIP) uninstall -y jupyterlab-lsp
  86. $(PYTHON_PIP) uninstall -y python-lsp-server
  87. $(PYTHON_PIP) uninstall -y jupyter-resource-usage
  88. - jupyter labextension uninstall @jupyter-server/resource-usage
  89. $(PYTHON_PIP) uninstall -y elyra
  90. - jupyter lab clean
  91. # remove Kubeflow Pipelines example components
  92. - $(PYTHON_PIP) uninstall -y elyra-examples-kfp-catalog
  93. # remove GitLab dependency
  94. - $(PYTHON_PIP) uninstall -y python-gitlab
  95. clean: purge uninstall ## Make a clean source tree and uninstall extensions
  96. ## Lint targets
  97. lint-dependencies:
  98. @$(PYTHON_PIP) install -q -r lint_requirements.txt
  99. lint-server: lint-dependencies
  100. $(PYTHON) -m flake8 elyra .github
  101. @echo $(BLACK_CMD)
  102. @$(BLACK_CMD) || (echo "Black formatting encountered issues. Use 'make black-format' to apply the suggested changes."; exit 1)
  103. black-format: # Apply black formatter to Python source code
  104. $(PYTHON) -m black .
  105. prettier-check-ui:
  106. yarn prettier:check
  107. eslint-check-ui:
  108. yarn eslint:check --max-warnings=0
  109. prettier-ui:
  110. yarn prettier
  111. eslint-ui:
  112. yarn eslint --max-warnings=0
  113. lint-ui: prettier-ui eslint-ui
  114. lint: lint-ui lint-server ## Run linters
  115. ## Library linking targets
  116. dev-link:
  117. - yarn link @elyra/pipeline-services
  118. - yarn link @elyra/pipeline-editor
  119. - lerna run link:dev
  120. dev-unlink:
  121. - yarn unlink @elyra/pipeline-services
  122. - yarn unlink @elyra/pipeline-editor
  123. - lerna run unlink:dev
  124. yarn install --force
  125. ## Build and install targets
  126. build-dependencies:
  127. @$(PYTHON_PIP) install -q --upgrade pip
  128. @$(PYTHON_PIP) install -q -r build_requirements.txt
  129. dev-dependencies:
  130. @$(PYTHON_PIP) install -q --upgrade pip
  131. @$(PYTHON_PIP) install -q jupyter-packaging
  132. yarn-install:
  133. yarn install
  134. build-ui: # Build packages
  135. yarn lerna run build --stream
  136. package-ui: build-dependencies yarn-install lint-ui build-ui
  137. package-ui-dev: dev-dependencies yarn-install dev-link lint-ui build-ui
  138. build-server: # Build backend
  139. $(PYTHON) -m setup bdist_wheel sdist
  140. uninstall-server-package:
  141. @$(PYTHON_PIP) uninstall elyra -y
  142. install-server-package: uninstall-server-package
  143. $(PYTHON_PIP) install --upgrade --upgrade-strategy $(UPGRADE_STRATEGY) "$(shell find dist -name "elyra-*-py3-none-any.whl")[kfp-tekton]"
  144. install-server: build-dependencies lint-server build-server install-server-package ## Build and install backend
  145. install: package-ui install-server check-install ## Build and install
  146. install-all: package-ui install-server install-examples install-gitlab-dependency check-install ## Build and install, including examples
  147. install-dev: package-ui-dev install-server install-examples install-gitlab-dependency check-install
  148. install-examples: ## Install example pipeline components
  149. # install Kubeflow Pipelines example components
  150. # -> https://github.com/elyra-ai/examples/tree/main/component-catalog-connectors/kfp-example-components-connector
  151. - $(PYTHON_PIP) install --upgrade elyra-examples-kfp-catalog
  152. install-gitlab-dependency:
  153. # install GitLab support for Airflow
  154. - $(PYTHON_PIP) install --upgrade python-gitlab
  155. check-install:
  156. jupyter server extension list
  157. jupyter labextension list
  158. watch: ## Watch packages. For use alongside jupyter lab --watch
  159. yarn lerna run watch --parallel
  160. release: yarn-install build-ui build-server ## Build wheel file for release
  161. elyra-image-env: ## Creates a conda env consisting of the dependencies used in images
  162. conda env remove -y -n $(ELYRA_IMAGE_ENV)
  163. conda create -y -n $(ELYRA_IMAGE_ENV) python=$(PYTHON_VERSION)
  164. if [ "$(PYTHON_VERSION)" == "3.7" ]; then \
  165. $(CONDA_ACTIVATE) $(ELYRA_IMAGE_ENV) && \
  166. $(PYTHON_PIP) install -r etc/generic/requirements-elyra-py37.txt && \
  167. conda deactivate; \
  168. else \
  169. $(CONDA_ACTIVATE) $(ELYRA_IMAGE_ENV) && \
  170. $(PYTHON_PIP) install -r etc/generic/requirements-elyra.txt && \
  171. conda deactivate; \
  172. fi
  173. ## Test targets
  174. test-dependencies:
  175. @$(PYTHON_PIP) install -q -r test_requirements.txt
  176. pytest:
  177. $(PYTHON) -m pytest -v --durations=0 --durations-min=60 elyra
  178. test-server: test-dependencies pytest # Run python unit tests
  179. test-ui-unit: # Run frontend jest unit tests
  180. yarn test:unit
  181. test-integration: # Run frontend cypress integration tests
  182. yarn test:integration
  183. test-integration-debug: # Open cypress integration test debugger
  184. yarn test:integration:debug
  185. test-ui: lint-ui test-ui-unit test-integration # Run frontend tests
  186. test: test-server test-ui ## Run all tests (backend, frontend and cypress integration tests)
  187. ## Doc targets
  188. docs-dependencies:
  189. @$(PYTHON_PIP) install -q -r docs/requirements.txt
  190. docs: docs-dependencies ## Build docs
  191. make -C docs clean html
  192. ## Docker targets
  193. elyra-image: # Build Elyra stand-alone container image
  194. @mkdir -p build/docker
  195. cp etc/docker/elyra/Dockerfile build/docker/Dockerfile
  196. cp etc/docker/elyra/start-elyra.sh build/docker/start-elyra.sh
  197. cp etc/docker/elyra/requirements.txt build/docker/requirements.txt
  198. @mkdir -p build/docker/elyra
  199. cp dist/elyra-$(ELYRA_VERSION)-py3-none-any.whl build/docker/
  200. $(CONTAINER_EXEC) buildx build \
  201. --progress=plain \
  202. --output=type=docker \
  203. --tag docker.io/$(ELYRA_IMAGE) \
  204. --tag quay.io/$(ELYRA_IMAGE) \
  205. --build-arg TAG=$(TAG) \
  206. --build-arg ELYRA_VERSION=$(ELYRA_VERSION) \
  207. build/docker/;
  208. publish-elyra-image: elyra-image # Publish Elyra stand-alone container image
  209. # this is a privileged operation; a `docker login` might be required
  210. $(CONTAINER_EXEC) push docker.io/$(ELYRA_IMAGE)
  211. $(CONTAINER_EXEC) push quay.io/$(ELYRA_IMAGE)
  212. # If we're building a release from main, tag latest and push
  213. if [ "$(IMAGE_IS_LATEST)" == "True" ]; then \
  214. $(CONTAINER_EXEC) tag docker.io/$(ELYRA_IMAGE) docker.io/$(ELYRA_IMAGE_LATEST); \
  215. $(CONTAINER_EXEC) push docker.io/$(ELYRA_IMAGE_LATEST); \
  216. $(CONTAINER_EXEC) tag quay.io/$(ELYRA_IMAGE) quay.io/$(ELYRA_IMAGE_LATEST); \
  217. $(CONTAINER_EXEC) push quay.io/$(ELYRA_IMAGE_LATEST); \
  218. fi
  219. kf-notebook-image: # Build elyra image for use with Kubeflow Notebook Server
  220. @mkdir -p build/docker-kubeflow
  221. cp etc/docker/kubeflow/* build/docker-kubeflow/
  222. cp dist/elyra-$(ELYRA_VERSION)-py3-none-any.whl build/docker-kubeflow/
  223. $(CONTAINER_EXEC) buildx build \
  224. --progress=plain \
  225. --output=type=docker \
  226. --tag docker.io/$(KF_NOTEBOOK_IMAGE) \
  227. --tag quay.io/$(KF_NOTEBOOK_IMAGE) \
  228. --build-arg TAG=$(TAG) \
  229. --build-arg ELYRA_VERSION=$(ELYRA_VERSION) \
  230. build/docker-kubeflow;
  231. publish-kf-notebook-image: kf-notebook-image # Publish elyra image for use with Kubeflow Notebook Server
  232. # this is a privileged operation; a `docker login` might be required
  233. $(CONTAINER_EXEC) push docker.io/$(KF_NOTEBOOK_IMAGE)
  234. $(CONTAINER_EXEC) push quay.io/$(KF_NOTEBOOK_IMAGE)
  235. # If we're building a release from main, tag latest and push
  236. if [ "$(IMAGE_IS_LATEST)" == "True" ]; then \
  237. $(CONTAINER_EXEC) tag docker.io/$(KF_NOTEBOOK_IMAGE) docker.io/$(KF_NOTEBOOK_IMAGE_LATEST); \
  238. $(CONTAINER_EXEC) push docker.io/$(KF_NOTEBOOK_IMAGE_LATEST); \
  239. $(CONTAINER_EXEC) tag quay.io/$(KF_NOTEBOOK_IMAGE) quay.io/$(KF_NOTEBOOK_IMAGE_LATEST); \
  240. $(CONTAINER_EXEC) push quay.io/$(KF_NOTEBOOK_IMAGE_LATEST); \
  241. fi
  242. container-images: elyra-image kf-notebook-image ## Build all container images
  243. $(CONTAINER_EXEC) images $(ELYRA_IMAGE)
  244. $(CONTAINER_EXEC) images quay.io/$(ELYRA_IMAGE)
  245. $(CONTAINER_EXEC) images $(KF_NOTEBOOK_IMAGE)
  246. $(CONTAINER_EXEC) images quay.io/$(KF_NOTEBOOK_IMAGE)
  247. publish-container-images: publish-elyra-image publish-kf-notebook-image ## Publish all container images
  248. validate-runtime-images: # Validates delivered runtime-images meet minimum criteria
  249. @required_commands=$(REQUIRED_RUNTIME_IMAGE_COMMANDS) ; \
  250. $(PYTHON_PIP) install jq ; \
  251. for file in `find etc/config/metadata/runtime-images -name "*.json"` ; do \
  252. image=`cat $$file | jq -e -r '.metadata.image_name'` ; \
  253. if [ $$? -ne 0 ]; then \
  254. echo ERROR: $$file does not define the image_name property ; \
  255. exit 1; \
  256. fi; \
  257. make validate-runtime-image image=$$image ; \
  258. done
  259. validate-runtime-image: # Validate that runtime image meets minimum criteria
  260. @required_commands=$(REQUIRED_RUNTIME_IMAGE_COMMANDS) ; \
  261. if [[ $$image == "" ]] ; then \
  262. echo "Usage: make validate-runtime-image image=<container-image-name>" ; \
  263. exit 1 ; \
  264. fi ; \
  265. $(PYTHON_PIP) install -q jq ; \
  266. fail=0; \
  267. echo "***********************************************************" ; \
  268. echo "Validating container image $$image" ; \
  269. echo "-----------------------------------------------------------" ; \
  270. echo "=> Loading container image ..." ; \
  271. docker inspect $$image > /dev/null 2>&1 ; \
  272. if [ $$? -ne 0 ]; then \
  273. echo Container image $$image is not present, pulling... ; \
  274. docker pull $$image ; \
  275. if [ $$? -ne 0 ]; then \
  276. echo "ERROR: pull of container image $$image failed" ; \
  277. exit 1; \
  278. fi; \
  279. fi; \
  280. for cmd in $$required_commands ; do \
  281. echo "=> Checking container image $$image for $$cmd..." ; \
  282. docker run --rm $$image which $$cmd > /dev/null 2>&1 ; \
  283. if [ $$? -ne 0 ]; then \
  284. echo "ERROR: Container image $$image does not meet criteria for command: $$cmd" ; \
  285. fail=1; \
  286. continue; \
  287. fi; \
  288. if [ $$cmd == "python3" ]; then \
  289. IMAGE_PYTHON3_MINOR_VERSION=`docker run --rm $$image $$cmd --version | cut -d' ' -f2 | cut -d'.' -f2` ; \
  290. if [[ $$IMAGE_PYTHON3_MINOR_VERSION -lt 8 ]]; then \
  291. echo "WARNING: Container image $$image requires Python 3.8 or greater for latest generic component dependency installation" ; \
  292. echo "=> Checking notebook execution..." ; \
  293. docker run -v $$(pwd)/etc/generic:/opt/elyra/ --rm $$image /bin/bash -c "python3 -m pip install -r /opt/elyra/requirements-elyra-py37.txt && \
  294. curl https://raw.githubusercontent.com/nteract/papermill/main/papermill/tests/notebooks/simple_execute.ipynb --output simple_execute.ipynb && \
  295. python3 -m papermill simple_execute.ipynb output.ipynb > /dev/null" ; \
  296. if [ $$? -ne 0 ]; then \
  297. echo "ERROR: Container image $$image does not meet Python requirements criteria in requirements-elyra-py37.txt" ; \
  298. fail=1; \
  299. fi; \
  300. elif [[ $$IMAGE_PYTHON3_MINOR_VERSION -ge 8 ]]; then \
  301. echo "=> Checking notebook execution..." ; \
  302. docker run -v $$(pwd)/etc/generic:/opt/elyra/ --rm $$image /bin/bash -c "python3 -m pip install -r /opt/elyra/requirements-elyra.txt && \
  303. curl https://raw.githubusercontent.com/nteract/papermill/main/papermill/tests/notebooks/simple_execute.ipynb --output simple_execute.ipynb && \
  304. python3 -m papermill simple_execute.ipynb output.ipynb > /dev/null" ; \
  305. if [ $$? -ne 0 ]; then \
  306. echo "ERROR: Image $$image does not meet Python requirements criteria in requirements-elyra.txt" ; \
  307. fail=1; \
  308. fi; \
  309. else \
  310. echo "ERROR: Container image $$image: unable to parse Python version" ; \
  311. fail=1; \
  312. fi; \
  313. fi; \
  314. done ; \
  315. if [ $(REMOVE_RUNTIME_IMAGE) -eq 1 ]; then \
  316. echo Removing container image $$image... ; \
  317. docker rmi $$image > /dev/null ; \
  318. fi; \
  319. echo "-----------------------------------------------------------" ; \
  320. if [ $$fail -eq 1 ]; then \
  321. echo "=> ERROR: Container image $$image is not a suitable Elyra runtime image" ; \
  322. exit 1 ; \
  323. else \
  324. echo "=> Container image $$image is a suitable Elyra runtime image" ; \
  325. fi; \