Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 54 additions & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI/CD Pipeline

on:
release:
types: [ published ]
types: [published]
push:
branches:
- '**'
Expand All @@ -19,6 +19,17 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Ruff
run: pip install ruff==0.8.4

- name: Run Ruff linter
run: ruff check app/ tests/

test:
name: Run Tests
runs-on: ubuntu-latest
Expand All @@ -28,6 +39,17 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
run: pip install -r requirements.txt

- name: Run tests with coverage
run: pytest --cov=app --cov-report=term-missing --cov-fail-under=80

build:
name: Build Docker Image
runs-on: ubuntu-latest
Expand All @@ -40,3 +62,34 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
if: github.event_name == 'release'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build Docker image (branch push — no push to registry)
if: github.event_name == 'push'
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
push: false
tags: fastapi-gitops-starter:build

- name: Build and push Docker image (release)
if: github.event_name == 'release'
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }}
ghcr.io/${{ github.repository }}:latest
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,31 @@ repos:
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-added-large-files
args: ["--maxkb=500"]
- id: check-yaml
exclude: ^helm/
- id: detect-private-key

- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)

- repo: https://github.com/PyCQA/bandit
rev: 1.8.3
hooks:
- id: bandit
args: ["-r", "app/", "-ll"]

- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets

- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
6 changes: 6 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ async def list_items():
}


@app.post("/api/items")
async def create_item(name: str, description: str):
"""Create a new item."""
return {"id": 999, "name": name, "description": description, "created": True}


@app.get("/api/items/{item_id}")
async def get_item(item_id: int):
"""Example endpoint to get a specific item by ID."""
Expand Down
19 changes: 19 additions & 0 deletions custom-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
replicaCount: 1

ingress:
enabled: true
className: "nginx"
hosts:
- host: minikube.test
paths:
- path: /GitOps-Starter
pathType: Prefix

app:
rootPath: "/GitOps-Starter"

autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 10
14 changes: 14 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@ def test_get_item():
assert data["id"] == 5
assert data["name"] == "Item 5"
assert "item number 5" in data["description"]


def test_create_item():
"""Test the create item endpoint."""
response = client.post(
"/api/items",
params={"name": "Test Item", "description": "A test item"},
)
assert response.status_code == 200
data = response.json()
assert data["id"] == 999
assert data["name"] == "Test Item"
assert data["description"] == "A test item"
assert data["created"] is True