diff --git a/.github/.ci-env-config b/.github/.ci-env-config new file mode 100644 index 0000000..fd2bccf --- /dev/null +++ b/.github/.ci-env-config @@ -0,0 +1,10 @@ +ENVIRONMENT_NAME=k8s +DB_ENGINE=django.db.backends.mysql +DB_NAME=test +DB_USER=testuser +DB_PASSWORD=testpassword +DB_HOST=mysql +DB_PORT=3306 +DJANGO_SECRET_KEY=secret +DEBUG=false +ROOT_URLCONF=urls.production \ No newline at end of file diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml new file mode 100644 index 0000000..4610576 --- /dev/null +++ b/.github/workflows/build-and-test.yaml @@ -0,0 +1,87 @@ +name: Build and Test + +on: + push: + branches: + - '**' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: rlespinasse/github-slug-action@v4 + - name: Check Out Repo + uses: actions/checkout@v2 + + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.K6_DOCKERHUB_USERNAME }} + password: ${{ secrets.K6_DOCKERHUB_TOKEN }} + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + context: ./ + file: ./k8s/Dockerfile + cache-from: type=gha,scope=dev + cache-to: type=gha,scope=dev,mode=max + push: true + tags: | + ${{ github.repository }}:${{ env.GITHUB_REF_NAME_SLUG }}-dev + ${{ github.repository }}:${{ github.sha }}-dev + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} + + Run-Tests: + runs-on: ubuntu-latest + needs: [build] + services: + test-api: + image: ${{ github.repository }}:${{ github.sha }}-dev + credentials: + username: ${{ secrets.K6_DOCKERHUB_USERNAME }} + password: ${{ secrets.K6_DOCKERHUB_TOKEN }} + env: + ENVIRONMENT_NAME: 'k8s' + DB_ENGINE: 'django.db.backends.mysql' + DB_NAME: 'test' + DB_USER: 'testuser' + DB_PASSWORD: 'testpassword' + DB_HOST: 'mysql' + DB_PORT: '3306' + DJANGO_SECRET_KEY: 'secret' + DEBUG: "false" + ROOT_URLCONF: "urls.production" + ports: + - 80:8000 + mysql: + image: mysql:5.7 + env: + MYSQL_DATABASE: test + MYSQL_USER: testuser + MYSQL_PASSWORD: testpassword + MYSQL_ROOT_PASSWORD: testrootpass + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.K6_DOCKERHUB_USERNAME }} + password: ${{ secrets.K6_DOCKERHUB_TOKEN }} + - name: Apply database migrations + run: | + docker run --env-file ${{ github.workspace }}/.github/.ci-env-config --network ${{ job.container.network }} ${{ github.repository }}:${{ github.sha }}-dev sh -c "python manage.py collectstatic --noinput -v1 && python manage.py migrate && python manage.py loaddata fixtures/initial.json" + - name: Run k6 http test + run: | + docker run --env BASE_URL="http://localhost:80" --network host -v ${{ github.workspace }}:/data/ grafana/k6:latest run /data/k6_tests/api_demo.js diff --git a/k8s/Dockerfile b/k8s/Dockerfile index 4da32d6..f7aa25e 100644 --- a/k8s/Dockerfile +++ b/k8s/Dockerfile @@ -1,17 +1,28 @@ -FROM python:3.9-slim-bullseye - -RUN apt-get update && apt-get -y upgrade && \ - export DEBIAN_FRONTEND=noninteractive && \ - apt-get -y install --no-install-recommends \ - gcc \ - default-libmysqlclient-dev && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -RUN useradd --uid 1000 --create-home appuser +FROM python:3.9-alpine + +ENV PYTHONUNBUFFERED 1 + +RUN adduser -u 82 -D -S -G www-data appuser + +RUN apk update && \ + apk upgrade && \ + apk add --no-cache \ + nginx \ + musl-dev \ + cargo \ + gcc \ + openssl-dev \ + libexpat \ + libffi-dev \ + build-base \ + mysql-dev \ + mariadb-connector-c-dev && \ + rm -r /usr/local/lib/python*/ensurepip && \ + pip3 install --upgrade pip==23.3 && \ + rm -r /root/.cache COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +RUN pip3 install --no-cache-dir -r requirements.txt USER appuser diff --git a/project/apps/api/apps.py b/project/apps/api/apps.py index 12ee74c..374b0a1 100644 --- a/project/apps/api/apps.py +++ b/project/apps/api/apps.py @@ -2,4 +2,4 @@ class Api1Config(AppConfig): - name = 'api' + name = "apps.api" diff --git a/project/settings/api/__init__.py b/project/settings/api/__init__.py index facd0eb..958d2cc 100644 --- a/project/settings/api/__init__.py +++ b/project/settings/api/__init__.py @@ -1,14 +1,14 @@ from os import environ env = environ.get("ENVIRONMENT_NAME") -if env == 'dev': +if env == "dev": from .dev import * -elif env == 'k8s': +elif env == "k8s": # In k8s setup settings come from env vars, specified in the Deployment api object and # configured in k8s ConfigMap or ExternalSecret api objects. - # Quering secrets from AWS Secret Manager is the responsibility of the k8s cluster. + # Quering secrets from AWS Secret Manager is the responsibility of the k8s cluster. from .k8s import * elif not env: from .default import * else: - raise Exception(f'ENVIRONMENT_NAME env incorrect: {env}') + raise Exception(f"ENVIRONMENT_NAME env incorrect: {env}") diff --git a/requirements.txt b/requirements.txt index 6f594c8..587982c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==3.1.14 +Django==3.2.24 channels==3.0.3 djangorestframework==3.12.4