Skip to content

Commit

Permalink
Merge pull request #14 from developmentseed/feature/add-deploy
Browse files Browse the repository at this point in the history
add actions to test and deploy
  • Loading branch information
vincentsarago authored Jan 31, 2024
2 parents b763dd1 + 0e44a84 commit 8d5c49a
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 1 deletion.
108 changes: 108 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Test and Deploy

# Triggers on pushes to main, dev and tags.
on:
workflow_dispatch:
push:
branches:
- main
- develop
tags:
- 'v*'
paths:
# Only run test and docker publish if some code have changed
- 'pyproject.toml'
- 'infrastructure/aws/**'
- 'titiler/**'
- '.pre-commit-config.yaml'
# Run tests on pull requests.
pull_request:
env:
LATEST_PY_VERSION: '3.10'

permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e .["test"]
- name: run pre-commit
if: ${{ matrix.python-version == env.LATEST_PY_VERSION }}
run: |
python -m pip install pre-commit
pre-commit run --all-files
- name: Run tests
run: python -m pytest --cov titiler.cmr --cov-report term-missing -s -vv

deploy:
# needs: [tests]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/v')

defaults:
run:
working-directory: infrastructure/aws

steps:
- uses: actions/checkout@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.role_arn }}
role-session-name: samplerolesession
aws-region: us-west-2

- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 18

- name: Install cdk
run: npm install -g aws-cdk

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements-cdk.txt
# Build and deploy to the development environment whenever there is a push to main or dev
- name: Build & Deploy Development
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
run: npm run cdk -- deploy titiler-cmr-staging --require-approval never
env:
# STACK_ALARM_EMAIL: ${{ secrets.ALARM_EMAIL }}
STACK_ROLE_ARN: ${{ secrets.role_arn }}
STACK_STAGE: staging

# Build and deploy to production deployment whenever there a new tag is pushed
- name: Build & Deploy Production
if: startsWith(github.ref, 'refs/tags/v')
run: npm run cdk -- deploy titiler-cmr-production --require-approval never
env:
# STACK_ALARM_EMAIL: ${{ secrets.ALARM_EMAIL }}
STACK_ROLE_ARN: ${{ secrets.role_arn }}
STACK_STAGE: production
14 changes: 14 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""titiler.cmr tests configuration."""

import pytest
from fastapi.testclient import TestClient


@pytest.fixture
def app(monkeypatch):
"""App fixture."""

from titiler.cmr.main import app

with TestClient(app) as client:
yield client
86 changes: 86 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""test titiler-cmr app."""


def test_landing(app):
"""Test / endpoint."""
response = app.get("/")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["title"] == "titiler-cmr"
assert body["links"]

response = app.get("/?f=html")
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]
assert "titiler-cmr" in response.text

# Check accept headers
response = app.get("/", headers={"accept": "text/html"})
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]
assert "titiler-cmr" in response.text

# accept quality
response = app.get(
"/", headers={"accept": "application/json;q=0.9, text/html;q=1.0"}
)
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]
assert "titiler-cmr" in response.text

# accept quality but only json is available
response = app.get("/", headers={"accept": "text/csv;q=1.0, application/json"})
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["title"] == "titiler-cmr"

# accept quality but only json is available
response = app.get("/", headers={"accept": "text/csv;q=1.0, */*"})
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["title"] == "titiler-cmr"

# Invalid accept, return default
response = app.get("/", headers={"accept": "text/htm"})
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["title"] == "titiler-cmr"
assert body["links"]

# make sure `?f=` has priority over headers
response = app.get("/?f=json", headers={"accept": "text/html"})
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["title"] == "titiler-cmr"


def test_docs(app):
"""Test /api endpoint."""
response = app.get("/api")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["openapi"]

response = app.get("/api.html")
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]


def test_conformance(app):
"""Test /conformance endpoint."""
response = app.get("/conformance")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
body = response.json()
assert body["conformsTo"]

response = app.get("/conformance?f=html")
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]
assert "Conformance" in response.text
38 changes: 38 additions & 0 deletions tests/test_tms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""test TileMatrixSets endpoints."""

from morecantile import tms


def test_tilematrix(app):
"""test /tileMatrixSet endpoint."""
response = app.get("/tileMatrixSets")
assert response.status_code == 200
body = response.json()

assert len(body["tileMatrixSets"]) == len(tms.list())
tileMatrixSets = list(
filter(lambda m: m["id"] == "WebMercatorQuad", body["tileMatrixSets"])
)[0]
assert (
tileMatrixSets["links"][0]["href"]
== "http://testserver/tileMatrixSets/WebMercatorQuad"
)

response = app.get("/tileMatrixSets?f=html")
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]


def test_tilematrixInfo(app):
"""test /tileMatrixSet endpoint."""
response = app.get("/tileMatrixSets/WebMercatorQuad")
assert response.headers["content-type"] == "application/json"
assert response.status_code == 200
body = response.json()
assert body["id"] == "WebMercatorQuad"
assert body["crs"]
assert body["tileMatrices"]

response = app.get("/tileMatrixSets/WebMercatorQuad?f=html")
assert response.status_code == 200
assert "text/html" in response.headers["content-type"]
1 change: 0 additions & 1 deletion titiler/cmr/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class ApiSettings(BaseSettings):
cors_origins: str = "*"
cachecontrol: str = "public, max-age=3600"
root_path: str = ""
debug: bool = False

model_config = {
"env_prefix": "TITILER_CMR_API_",
Expand Down

0 comments on commit 8d5c49a

Please sign in to comment.