Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0621e40
chore: added .pytest_cache to .gitignore
guifry Feb 9, 2024
3ea3238
test(e2e): initial Playwright setup with dummy test
guifry Feb 9, 2024
cbb1b64
test(e2e): compose config for playwright UI
guifry Feb 9, 2024
d20e9a0
test(e2e): WIP - trying to simplify the docker-compose
guifry Feb 9, 2024
de172b6
test(e2e): rollback yaml fragments
guifry Feb 9, 2024
7fb20d5
test(e2e): simplify the api config variables
guifry Feb 9, 2024
b3b8151
test(e2e): add codegen to docker-compose
guifry Feb 10, 2024
1d63e2d
chore: simplify the life out of the Makefile
guifry Feb 10, 2024
bb501bc
chore: same .nvmrc for client and e2e
guifry Feb 10, 2024
953f481
test(e2e): write first real test with Playwright
guifry Feb 10, 2024
1b13235
chore: .Dockerfile e2e: npm ci not i
guifry Feb 10, 2024
75e7371
chore(e2e): get rid of dummy Playwright tests
guifry Feb 10, 2024
c9f767b
chore(e2e): get rid of wait_for_url.py yipee
guifry Feb 10, 2024
341f270
chore: new .envrc.template
guifry Feb 10, 2024
48e8499
progress
guifry Feb 16, 2024
b8b832b
chore: delete .github playwright workflows , will add them in next PR
guifry Feb 16, 2024
2648282
chore: fix test client command in github workflow
guifry Feb 16, 2024
bf43f8b
chore: pre-commit
guifry Feb 16, 2024
d6103d7
chore: remove eslint from precommit
guifry Feb 16, 2024
9268a91
fix(e2e): imrpove stability, remove timeouts, fix assertCookie() util by
guifry Mar 8, 2024
70e50c3
chore(CI): fix E2E CI
guifry Mar 8, 2024
ce6e02a
tryna fix playwright container
guifry Mar 8, 2024
84f032b
progress on this issue
guifry Mar 8, 2024
5e931f2
fix(e2e): playwright container works in CI
guifry Mar 10, 2024
e2e0723
Add back the timeouts
guifry Mar 10, 2024
98434ed
progress
guifry Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .envrc.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export APP_NAME=consent_api
export DOCKER_IMAGE=gcr.io/sde-consent-api/consent-api
export SPLINTER_REMOTE_BROWSER_VERSION=sskorol/selenoid_chromium_vnc:100.0
export ENV=development
export PULUMI_ACCESS_TOKEN=abc
8 changes: 2 additions & 6 deletions .github/workflows/open-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ jobs:
cache-dependency-path: "./client/package-lock.json"

- run: cd client && npm ci
- run: make test-client
- run: cd client && npm run test

build-test-push:
runs-on: ubuntu-latest

env:
BRANCH_NAME: ${{ github.head_ref }}
CHROME_VERSION: "110.0"
SPLINTER_REMOTE_BROWSER_VERSION: "110.0"

permissions:
contents: write
Expand Down Expand Up @@ -82,9 +80,7 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

- run: docker pull selenoid/chrome:${{ env.CHROME_VERSION }}

- run: make test-end-to-end-docker
- run: ENV=development CI=true make docker-e2e
name: Run tests
env:
DOCKER_IMAGE: ${{ env.IMAGE_TAG }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ __pycache__
.envrc
.vscode
openapi.json
.pytest_cache
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.18.1
18
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ci:
autoupdate_commit_msg: |
[pre-commit.ci] pre-commit autoupdate [norelease]

exclude: ^migrations/
exclude: ^migrations/ ^static/ ^node_modules/ ^e2e-tests/tests/\w.spec.ts

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
Expand Down
208 changes: 103 additions & 105 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,84 +1,125 @@
-include .envrc

APP_NAME ?= consent_api
DATABASE_URL ?= postgresql+asyncpg://localhost:5432/$(APP_NAME)
DOCKER ?= docker
DOCKER_BUILD ?= docker buildx build
DOCKER_DB_URL ?= postgresql+asyncpg://postgres@host.docker.internal:5432/$(APP_NAME)
DOCKER_IMAGE ?= gcr.io/sde-consent-api/consent-api
TAG ?= latest
ENV ?= development
PORT ?= 8000
PREVIEW := $(shell \
echo $${PREVIEW:+--preview} \
)
SELENIUM_DRIVER ?= chrome
SPLINTER_REMOTE_BROWSER_VERSION ?= ""
SPLINTER_REMOTE_URL := $(shell \
echo $${SELENIUM_REMOTE_URL:+--splinter-remote-url $${SELENIUM_REMOTE_URL}} \
)

## clean: Remove temporary files
.PHONY: clean
clean:
find . \( -name '__pycache__' -and -not -name ".venv" \) -depth -prune -exec rm -r {} +

# ---------------------------------------------------------------------------------
# STARTUP COMMANDS
# ---------------------------------------------------------------------------------
# Commands that start the project in different modes

.PHONY: docker-run docker-e2e docker-e2e-ui docker-e2e-debug

docker-run:
docker-compose --profile local up

docker-e2e:
docker-compose --profile test up

docker-e2e-ui:
docker-compose --profile test-ui up

docker-e2e-debug:
docker-compose --profile debug up

docker-e2e-codegen:
docker-compose --profile codegen up playwright-codegen



# ---------------------------------------------------------------------------------
# PROJECT SETUP COMMANDS
# ---------------------------------------------------------------------------------
# Use this section for commands that help set up the project, like installing dependencies, setting up databases, etc.

.PHONY: install migrations new-migration

## install: Install dependencies
.PHONY: install
install:
curl -sSL https://install.python-poetry.org | python3 -
install: install-consent-api install-client install-e2e-tests

install-consent-api:
@command -v poetry >/dev/null 2>&1 || { echo >&2 "Poetry is not installed. Please install it by following the instructions at https://python-poetry.org/docs/#installation"; exit 1; }
poetry install

.PHONY: check
check:
black --check .
ruff check .
install-client:
cd client && npm install && npm run build

.PHONY: fix
fix:
pre-commit run --all-files
install-e2e-tests:
cd e2e-tests && npm install



# ---------------------------------------------------------------------------------
# DB COMMANDS
# ---------------------------------------------------------------------------------
# Commands for managing the database

## migrations: Run all database migrations
.PHONY: migrations
migrations:
alembic --config migrations/alembic.ini upgrade head

## new-migration: Generate a new database migration from model code
.PHONY: new-migration
new-migration:
alembic --config migrations/alembic.ini revision --autogenerate

## test: Run tests
.PHONY: test


# ---------------------------------------------------------------------------------
# INFRA COMMANDS
# ---------------------------------------------------------------------------------
# Infrastructure-related commands, like IaC, Pulumi setups & deployments, etc.

.PHONY: infra infra-destroy deploy destroy-deployment

## infra: Create/update a deployment environment
infra:
python infra/setup_env.py -e $(ENV) $(PREVIEW)

## infra-destroy: Destroy a deployment environment
infra-destroy:
python infra/setup_env.py --destroy -e $(ENV) $(PREVIEW)

## deploy: Deploy the service to an environment
deploy:
python infra/deploy.py -e $(ENV) $(PREVIEW) -b main

destroy-deployment:
python infra/deploy.py --destroy -e $(ENV) $(PREVIEW) -b main



# ---------------------------------------------------------------------------------
# Linting / Formatting
# ---------------------------------------------------------------------------------
# Commands for linting and formatting code

.PHONY: fix check

fix:
pre-commit run --all-files

check:
black --check .
ruff check .


# ---------------------------------------------------------------------------------
# OTHER
# ---------------------------------------------------------------------------------
# Use this section for miscellaneous commands that don't fit into the above categories.

.PHONY: clean test

## clean: Remove temporary files
clean:
find . \( -name '__pycache__' -and -not -name ".venv" \) -depth -prune -exec rm -r {} +


test:
pytest -x -n=auto --dist=loadfile -W ignore::DeprecationWarning -m "not end_to_end"

.PHONY: test-client
test-client:
cd client && npm test

## test-end-to-end: Run webdriver tests
.PHONY: test-end-to-end
test-end-to-end: migrations
# test-end-to-end:
python consent_api/tests/wait_for_url.py $(E2E_TEST_CONSENT_API_URL)
python consent_api/tests/wait_for_url.py $(E2E_TEST_DUMMY_SERVICE_1_URL)
python consent_api/tests/wait_for_url.py $(E2E_TEST_DUMMY_SERVICE_2_URL)
pytest \
-s \
-W ignore::DeprecationWarning \
-m end_to_end \
--splinter-webdriver $(SELENIUM_DRIVER) \
$(SPLINTER_REMOTE_URL) \
--splinter-headless


.PHONY: test-end-to-end-docker
test-end-to-end-docker:
ENV=testing COMPOSE_PROFILES=testing $(DOCKER) compose up --exit-code-from test

.PHONY: test-all
test-all: migrations test test-end-to-end

.PHONY: test-coverage
test-coverage:
Expand All @@ -88,64 +129,21 @@ test-coverage:
.PHONY: run
run:
ifeq ($(ENV),development)
uvicorn $(APP_NAME):app --reload --host "0.0.0.0" --port $(PORT) --proxy-headers --forwarded-allow-ips="*"
uvicorn consent_api:app --reload --host "0.0.0.0" --port $(PORT) --proxy-headers --forwarded-allow-ips="*"
else ifeq ($(ENV),testing)
uvicorn $(APP_NAME):app --reload --host "0.0.0.0" --port $(PORT) --proxy-headers --forwarded-allow-ips="*"
uvicorn consent_api:app --reload --host "0.0.0.0" --port $(PORT) --proxy-headers --forwarded-allow-ips="*"
else
gunicorn $(APP_NAME):app --worker-class uvicorn.workers.UvicornWorker --bind "0.0.0.0:$(PORT)" --forwarded-allow-ips="*"
gunicorn consent_api:app --worker-class uvicorn.workers.UvicornWorker --bind "0.0.0.0:$(PORT)" --forwarded-allow-ips="*"
endif


## docker-build: Build a Docker image
.PHONY: docker-build
docker-build: clean
$(DOCKER_BUILD) --platform linux/amd64 --tag $(DOCKER_IMAGE):$(TAG) .

## docker-run: Start a Docker container
.PHONY: docker-run
docker-run:
$(DOCKER) run \
--interactive \
--tty \
--rm \
--env DATABASE_URL="$(DOCKER_DB_URL)" \
--env PORT="$(PORT)" \
--publish $(PORT):$(PORT) \
$(DOCKER_IMAGE)

## infra: Create/update a deployment environment
.PHONY: infra
infra:
python infra/setup_env.py -e $(ENV) $(PREVIEW)

## infra-destroy: Destroy a deployment environment
.PHONY: infra-destroy
infra-destroy:
python infra/setup_env.py --destroy -e $(ENV) $(PREVIEW)

## deploy: Deploy the service to an environment
.PHONY: deploy
deploy:
python infra/deploy.py -e $(ENV) $(PREVIEW) -b main
docker buildx build --platform linux/amd64 --tag $(DOCKER_IMAGE):$(TAG) .

.PHONY: destroy-deployment
destroy-deployment:
python infra/deploy.py --destroy -e $(ENV) $(PREVIEW) -b main

## dist: Build client distribution file
.PHONY: dist
dist:
@mkdir -p client/dist
$(shell echo ";(function () {\n\n$$(cat client/src/singleconsent.js)\n\n})();\n" > "client/dist/singleconsent.js")
@echo client/dist/singleconsent.js written

## help: Show this message
.PHONY: help
help: Makefile
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'


## Generage openapi.json
.PHONY: generate-openapi
generate-openapi:
python scripts/generate_openapi.py
47 changes: 12 additions & 35 deletions consent_api/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
"""App configuration."""

import os
from enum import Enum

from dotenv import load_dotenv

from consent_api.config import defaults


class Environment(Enum):
DEVELOPMENT = "development"
STAGING = "staging"
TESTING = "testing"
PRODUCTION = "production"

from consent_api.config.types import Environment

load_dotenv()

Expand All @@ -36,32 +29,16 @@ class Environment(Enum):
CONSENT_EXPIRY_DAYS = 7


CONSENT_API_ORIGIN = {
Environment.TESTING: "http://consent-api",
Environment.DEVELOPMENT: os.getenv(
"CONSENT_API_ORIGIN", defaults.DEV.DEFAULT_CONSENT_API_ORIGIN
),
Environment.STAGING: os.getenv(
"CONSENT_API_ORIGIN", defaults.STAGING.DEFAULT_CONSENT_API_ORIGIN
),
Environment.PRODUCTION: os.getenv(
"CONSENT_API_ORIGIN", defaults.PROD.DEFAULT_CONSENT_API_ORIGIN
),
}.get(Environment(ENV), defaults.DEV.DEFAULT_CONSENT_API_ORIGIN)


OTHER_SERVICE_ORIGIN = {
Environment.TESTING: os.getenv(
"OTHER_SERVICE_ORIGIN_DOCKER", defaults.DEV.DEFAULT_OTHER_SERVICE_ORIGIN
),
Environment.DEVELOPMENT: os.getenv(
"OTHER_SERVICE_ORIGIN_HOST", defaults.DEV.DEFAULT_OTHER_SERVICE_ORIGIN
),
Environment.STAGING: os.getenv(
"OTHER_SERVICE_ORIGIN_HOST", defaults.STAGING.DEFAULT_OTHER_SERVICE_ORIGIN
),
Environment.PRODUCTION: defaults.PROD.DEFAULT_OTHER_SERVICE_ORIGIN,
}.get(Environment(ENV), defaults.DEV.DEFAULT_OTHER_SERVICE_ORIGIN)
default_api_origin = defaults.consent_api_origins.get(
Environment(ENV), defaults.consent_api_origins[Environment.DEVELOPMENT]
)

default_other_service_origin = defaults.other_service_origins.get(
Environment(ENV), defaults.other_service_origins[Environment.DEVELOPMENT]
)

CONSENT_API_ORIGIN = os.getenv("CONSENT_API_ORIGIN", default_api_origin)
OTHER_SERVICE_ORIGIN = os.getenv("OTHER_SERVICE_ORIGIN", default_other_service_origin)


FLAG_FIXTURES = os.getenv("FLAG_FIXTURES", False) == "True"
23 changes: 13 additions & 10 deletions consent_api/config/defaults.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
class DEV:
DEFAULT_CONSENT_API_ORIGIN = "http://consent-api"
DEFAULT_OTHER_SERVICE_ORIGIN = "http://dummy-service-1"
from consent_api.config.types import Environment

other_service_origins = {
Environment.TESTING: "http://dummy-service-1",
Environment.DEVELOPMENT: "http://dummy-service-1",
Environment.STAGING: "",
Environment.PRODUCTION: "",
}

class STAGING:
DEFAULT_CONSENT_API_ORIGIN = "https://gds-single-consent-staging.app"
DEFAULT_OTHER_SERVICE_ORIGIN = ""


class PROD:
DEFAULT_CONSENT_API_ORIGIN = "https://gds-single-consent.app"
DEFAULT_OTHER_SERVICE_ORIGIN = ""
consent_api_origins = {
Environment.TESTING: "http://consent-api",
Environment.DEVELOPMENT: "http://consent-api",
Environment.STAGING: "https://gds-single-consent-staging.app",
Environment.PRODUCTION: "https://gds-single-consent.app",
}
Loading