diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b1e08a..866bdab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -46,9 +46,17 @@ references: branches: only: master + docker_login: &docker_login run: docker login -u $DOCKER_USER -p $DOCKER_PASSWORD + install_deps: &install_deps + run: + command: | + apt-get update + apt-get install wget git -y + wget https://github.com/mikefarah/yq/releases/download/v4.27.5/yq_linux_amd64 -O /usr/bin/yq &&\ + chmod +x /usr/bin/yq jobs: checkout_code_upver: @@ -86,23 +94,24 @@ jobs: - run: apt install make -y - run: make build-and-upload - deploy_demo: + deploy_demo_argo: docker: - - image: google/cloud-sdk:latest + - image: ubuntu:focal working_directory: ~/demo steps: - add_ssh_keys - *disable_strict_git - *load_cache - *setup_workspace - - *auth_google - *load_version - - run: git clone git@github.com:Rookout/deployment-demo - - run: apt install make -y - - run: export GOOGLE_APPLICATION_CREDENTIALS=/root/demo/gcp-key.json && cd deployment-demo && export env=staging && make install-helm deploy-demo - - run: export GOOGLE_APPLICATION_CREDENTIALS=/root/demo/gcp-key.json && cd deployment-demo && export env=production && make install-helm deploy-demo - - run: export GOOGLE_APPLICATION_CREDENTIALS=/root/demo/gcp-key.json && cd deployment-demo && export env=sandbox && make install-helm deploy-demo - - run: export GOOGLE_APPLICATION_CREDENTIALS=/root/demo/gcp-key.json && cd deployment-demo && export env=staging-sandbox && make install-helm deploy-demo + - *install_deps + - run: git config --global user.email "sonario@rookout.com" && git config --global user.name "sonariorobot" + - run: git clone git@github.com:Rookout/gitops.git + - run: PUBLISH_VERSION=$(echo $NEW_VERSION | sed 's/inner-999/1/g') yq eval -i -v '.apps[] |= select(.chart.name == "tutorial-python").helmValues.image.tag = strenv(PUBLISH_VERSION)' gitops/apps/demo/staging/apps.yaml + - run: PUBLISH_VERSION=$(echo $NEW_VERSION | sed 's/inner-999/1/g') yq eval -i -v '.apps[] |= select(.chart.name == "tutorial-python").helmValues.image.tag = strenv(PUBLISH_VERSION)' gitops/apps/demo/production/apps.yaml + - run: cd gitops && git add apps/demo/staging/apps.yaml apps/demo/production/apps.yaml + - run: cd gitops && git commit -m "update tutorial-python $NEW_VERSION" + - run: cd gitops && git push https://sonariorobot:$GITHUB_TOKEN@github.com/Rookout/gitops.git test_demo_servers_up: docker: @@ -110,11 +119,11 @@ jobs: working_directory: ~/demo steps: - run: sleep 15 && echo "Checking Staging..." - - run: curl 'http://staging.machina.rookout-demo.com/account/register' - - run: curl 'http://staging.python.rookout-demo.com/' - - run: curl 'http://staging.java.rookout-demo.com/' - - run: curl 'http://staging.nodejs.rookout-demo.com/' - - run: curl 'http://staging.ruby.rookout-demo.com/' + - run: curl 'https://machina.staging.rookout-demo.com/account/register' + - run: curl 'https://python.staging.rookout-demo.com/' + - run: curl 'https://java.staging.rookout-demo.com/' + - run: curl 'https://nodejs.staging.rookout-demo.com/' + - run: curl 'https://ruby.staging.rookout-demo.com/' - run: sleep 15 && echo "Checking Production..." - run: curl 'http://machina.rookout-demo.com/account/register' - run: curl 'http://python.rookout-demo.com/' @@ -139,13 +148,13 @@ workflows: requires: - checkout_code_upver <<: *filter_master - - deploy_demo: + - deploy_demo_argo: requires: - build_and_push_demo_image <<: *filter_master - test_demo_servers_up: requires: - - deploy_demo + - deploy_demo_argo <<: *filter_master - notify_slack: requires: diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..b3c6238 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,21 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/python-3/.devcontainer/base.Dockerfile + +# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster +ARG VARIANT="3.8-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="14" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image. +# COPY requirements.txt /tmp/pip-tmp/ +# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ +# && rm -rf /tmp/pip-tmp + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..144ac44 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,48 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/python-3 +{ + "name": "Python 3", + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": { + // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6 + // Append -bullseye or -buster to pin to an OS version. + // Use -bullseye variants on local on arm64/Apple Silicon. + "VARIANT": "3.8-bullseye", + // Options + "NODE_VERSION": "14" + } + }, + + // Set *default* container specific settings.json values on container create. + "settings": { + "python.defaultInterpreterPath": "/usr/local/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", + "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", + "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", + "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "pip3 install --user -r requirements.txt", + + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} diff --git a/.jenkins/Jenkinsfile.test b/.jenkins/Jenkinsfile.test index f08e060..f7d992a 100644 --- a/.jenkins/Jenkinsfile.test +++ b/.jenkins/Jenkinsfile.test @@ -1,7 +1,7 @@ regressionTest { FILE_PATH = "app.py" LINE_NUM = "114" - SHA = "6833c3840a3542adddde98bceaa1aa715d49cf29b5295b6b3e84817a0b967129" + SHA = "3658556546f8bb925e5be01da38432f0a924d48f9c05bfbe0c40981dbf34ca66" LANG = "Python" BACKGROUND_IMAGE_CMD = "python /app/app.py &" URL_FOR_TRIGGER = "http://localhost:5000/todos" diff --git a/Dockerfile b/Dockerfile index e653b1f..3ea0b54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.8-slim # pip installing the requirements.txt requires git because we're installing a fork RUN apt-get -y update -RUN apt-get -y install git +RUN apt-get -y install git wget ARG GIT_COMMIT=unspecified ENV ROOKOUT_COMMIT=$GIT_COMMIT diff --git a/README.md b/README.md index bb133a9..28fcbc8 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ python app.py docker run -p 5000:5000 -e ROOKOUT_TOKEN=$ROOKOUT_TOKEN rookout/tutorial-python ``` +**Note:** On M1-based Macbook laptops, port 5000 is already in use by default, so changing the port binding (`5001:5000` for example) may be required. + ## Usage - Log in to the [Rookout IDE](https://app.rookout.com/) diff --git a/app.py b/app.py index d39a9ae..498207f 100644 --- a/app.py +++ b/app.py @@ -6,18 +6,18 @@ from datetime import datetime from random import randint from todos_store import Store -import sentry_sdk -from sentry_sdk.integrations.flask import FlaskIntegration + + from jaeger_client import Config from flask_opentracing import FlaskTracer from utils.logging import on_add_todo_logging, on_get_todos_logging import os from flask import send_from_directory -sentry_sdk.init( - dsn="https://2acefaf842814814848afd40457bc55d@sentry.io/1381062", - integrations=[FlaskIntegration()] -) + + + + app = flask.Flask(__name__, static_url_path='/static') @@ -128,6 +128,13 @@ def duplicate_todo(todoId): break return '', 204 + +@app.route('/todos/remove_all', methods=['DELETE']) +def remove_all(): + Store.getInstance().todos = [] + return '', 204 + + @app.route('/favicon.ico') def favicon(): return send_from_directory(os.path.join(app.root_path, 'static'), 'rookout_favicon.ico', mimetype='image/vnd.microsoft.icon') diff --git a/requirements.txt b/requirements.txt index 2125a02..5b11b4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ -rook>=0.1.164 +rook>=0.1.209 flask>=1.0,<=2.0 -sentry-sdk[flask]>=0.6.9 -e git+https://github.com/Rookout/python-flask.git@e56318f9c84978ecdaeaaff4aa819dc86f5509c7#egg=Flask_OpenTracing jaeger-client +protobuf>=3.18.3 # not directly required, pinned by Snyk to avoid a vulnerability +werkzeug==2.3.7 diff --git a/static/css/style.css b/static/css/style.css index 1013c60..b314064 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -373,6 +373,11 @@ html .clear-completed:active { text-decoration: underline; } +.clear-all-items { + cursor: pointer; +} + + /* Hack to remove background from Mobile Safari. Can't use it globally since it destroys checkboxes in Firefox diff --git a/static/index.html b/static/index.html index 00334ef..c300598 100644 --- a/static/index.html +++ b/static/index.html @@ -42,6 +42,7 @@

todos

diff --git a/static/js/app.js b/static/js/app.js index c5102a8..48ad7c8 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -61,6 +61,12 @@ $().ready(() => { method: 'DELETE' }); this.reloadOnFinish(action); + }, + removeAll() { + const action = $.ajax('/todos/remove_all', { + method: 'DELETE' + }); + this.reloadOnFinish(action); }, updateTodo(todo) { const action = $.ajax('/todos', {