From 3d17520f8acb372bf01eca511687017540143885 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 11 Feb 2026 14:55:37 +0100 Subject: [PATCH 1/8] added: endpoint and workflow --- .github/workflows/ci-cd.yml | 24 ++++++++++++++++++++++++ .github/workflows/markdown2pdf.yml | 2 +- .pre-commit-config.yaml | 6 ++++++ README.md | 28 ++++++++++++++-------------- app/main.py | 6 ++++++ requirements.txt | 6 +++--- tests/test_main.py | 14 ++++++++++++++ 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a98b15e..b867624 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -19,6 +19,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Lint code + run: ruff check app/ tests/ --fix + + test: name: Run Tests runs-on: ubuntu-latest @@ -28,6 +32,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Run coverage test + run: pytest --cov=app --cov-report=html --cov-fail-under=80 + build: name: Build Docker Image runs-on: ubuntu-latest @@ -40,3 +47,20 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + + - name: Build docker image + run: docker build -t fastapi-gitops-starter . + + - name: Add tag image on release + if: github.event_name == 'release' + run: | + docker tag fastapi-gitops-starter:latest \ + fastapi-gitops-starter:${{ github.ref_name }} + + - name: Push Docker image + run: | + docker push fastapi-gitops-starter:latest + if [ "${GITHUB_EVENT_NAME}" = "release" ]; then + docker push fastapi-gitops-starter:${GITHUB_REF_NAME} + fi + diff --git a/.github/workflows/markdown2pdf.yml b/.github/workflows/markdown2pdf.yml index fcb4671..4177b58 100644 --- a/.github/workflows/markdown2pdf.yml +++ b/.github/workflows/markdown2pdf.yml @@ -19,7 +19,7 @@ jobs: - name: Replace links run: | - cp README.md README_WITH_LINKS.md + cp README.md README_WITH_LINKS.md sed -i -e "s#\(^\!\[[^]]\+\](\)\(images/\)#\1$URL/\2#g" README_WITH_LINKS.md for file in sources/*; do sed -i -e "s#($file)#($URL/$file)#g" README_WITH_LINKS.md ; done diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d337d10..ac3c529 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,3 +3,9 @@ repos: rev: v5.0.0 hooks: - id: trailing-whitespace + - id: check-added-large-files + - id: check-yaml + exclude: "helm/.*\\.yaml" + - id: requirements-txt-fixer + - id: detect-private-key + - id: check-ast diff --git a/README.md b/README.md index 79bb814..057f54d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ GitOps with FastAPI ***University of Amsterdam*** -# 1. Introduction +# 1. Introduction In this tutorial, we use GitOps practices with FastAPI, including CI/CD pipelines, code quality tools, and automated testing. @@ -35,7 +35,7 @@ In this tutorial, we use GitOps practices with FastAPI, including CI/CD pipeline -# 2. Tutorial +# 2. Tutorial The steps of this tutorial are as follows: - [Building REST APIs with FastAPI](#21-setting-up-the-project) @@ -60,17 +60,17 @@ Prerequisites: ``` * Set Up the Python Environmentt: - + ```bash # Create a virtual environment python -m venv venv - + # Activate the virtual environment # On Linux/MacOS: source venv/bin/activate # On Windows: venv\Scripts\activate - + # Install dependencies pip install -r requirements.txt ``` @@ -110,7 +110,7 @@ Prerequisites: ```bash # Check for issues ruff check app/ tests/ - + # Fix auto-fixable issues ruff check app/ tests/ --fix ``` @@ -120,7 +120,7 @@ Prerequisites: ```bash # Check formatting black --check app/ tests/ - + # Format code black app/ tests/ ``` @@ -134,7 +134,7 @@ Pre-commit hooks automatically run checks before each commit to ensure consisten ```bash # Install pre-commit pip install pre-commit - + # Install the git hooks pre-commit install ``` @@ -142,11 +142,11 @@ Pre-commit hooks automatically run checks before each commit to ensure consisten * Using Pre-commit: Pre-commit will now run automatically on `git commit`. You can also run it manually: - + ```bash # Run on all files pre-commit run --all-files - + # Run on staged files pre-commit run ``` @@ -200,14 +200,14 @@ This repository includes a Helm chart for deploying the application to Kubernete - Kubernetes 1.19+ - Helm 3.0+ -* Install the Helm Chart: +* Install the Helm Chart: ```bash helm install my-release ./helm/fastapi-gitops-starter ``` -* Uninstall the Helm Chart: - +* Uninstall the Helm Chart: + ```bash helm uninstall my-release ``` @@ -239,7 +239,7 @@ including host and paths. * To make sure we do not commit secrets * To check code style - + ## 3.2 Add a New Endpoint 1. Open `app/main.py` diff --git a/app/main.py b/app/main.py index ae8adc6..30abb95 100644 --- a/app/main.py +++ b/app/main.py @@ -49,5 +49,11 @@ async def get_item(item_id: int): } +@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} + + if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/requirements.txt b/requirements.txt index 0bdaab5..130e6a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ +black==24.10.0 fastapi==0.115.5 -uvicorn[standard]==0.32.1 +httpx==0.28.1 pytest==8.3.4 pytest-cov==6.0.0 -httpx==0.28.1 ruff==0.8.4 -black==24.10.0 +uvicorn[standard]==0.32.1 diff --git a/tests/test_main.py b/tests/test_main.py index db89e2f..b942761 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -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_post_item(): + """Test the post an item to endpoint.""" + response = client.post( + "/api/items", + params={"name": "NewItem", "description": "This is a newly added item"}, + ) + assert response.status_code == 200 + data = response.json() + assert data["id"] == 999 + assert data["name"] == "NewItem" + assert data["description"] == "This is a newly added item" + assert data["created"] From 1d29b1e5ef1a3492df9f1aa9ef825ff5c5223455 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 11 Feb 2026 14:59:31 +0100 Subject: [PATCH 2/8] added: python modules --- .github/workflows/ci-cd.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index b867624..79737ff 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -19,6 +19,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - run: pip install -r requirements.txt + - name: Lint code run: ruff check app/ tests/ --fix @@ -32,6 +38,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - run: pip install -r requirements.txt + - name: Run coverage test run: pytest --cov=app --cov-report=html --cov-fail-under=80 @@ -48,6 +60,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - run: pip install -r requirements.txt + - name: Build docker image run: docker build -t fastapi-gitops-starter . From 11f9e80653f8f85be8181c89b647f58618a6f472 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 11 Feb 2026 15:02:46 +0100 Subject: [PATCH 3/8] added: dockerfile location --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 79737ff..5ae0068 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -67,7 +67,7 @@ jobs: - run: pip install -r requirements.txt - name: Build docker image - run: docker build -t fastapi-gitops-starter . + run: docker build -t fastapi-gitops-starter:latest -f docker/Dockerfile . - name: Add tag image on release if: github.event_name == 'release' From b168779a9b53b77381fc483c8b47114433b34626 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 11 Feb 2026 15:12:19 +0100 Subject: [PATCH 4/8] added: username for docker --- .github/workflows/ci-cd.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 5ae0068..5817b64 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -60,25 +60,22 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - with: - python-version: 3.11 - - - run: pip install -r requirements.txt + - name: Log in to Docker Hub + run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - name: Build docker image - run: docker build -t fastapi-gitops-starter:latest -f docker/Dockerfile . + run: docker build -t ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest -f docker/Dockerfile . - name: Add tag image on release if: github.event_name == 'release' run: | - docker tag fastapi-gitops-starter:latest \ - fastapi-gitops-starter:${{ github.ref_name }} + docker tag ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest \ + ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:${{ github.ref_name }} - name: Push Docker image run: | - docker push fastapi-gitops-starter:latest + docker push ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest if [ "${GITHUB_EVENT_NAME}" = "release" ]; then - docker push fastapi-gitops-starter:${GITHUB_REF_NAME} + docker push ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:${GITHUB_REF_NAME} fi From 180a640efbdeebaf97ce690925d697edc681a74d Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 11 Feb 2026 15:14:14 +0100 Subject: [PATCH 5/8] fix: secret names --- .github/workflows/ci-cd.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 5817b64..f0cfeb8 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -61,21 +61,21 @@ jobs: uses: actions/checkout@v4 - name: Log in to Docker Hub - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + run: echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin - name: Build docker image - run: docker build -t ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest -f docker/Dockerfile . + run: docker build -t ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest -f docker/Dockerfile . - name: Add tag image on release if: github.event_name == 'release' run: | - docker tag ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest \ - ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:${{ github.ref_name }} + docker tag ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest \ + ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:${{ github.ref_name }} - name: Push Docker image run: | - docker push ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:latest + docker push ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest if [ "${GITHUB_EVENT_NAME}" = "release" ]; then - docker push ${{ secrets.DOCKER_USERNAME }}/fastapi-gitops-starter:${GITHUB_REF_NAME} + docker push ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:${GITHUB_REF_NAME} fi From 02a297d43f84599efef5474586631d4fe43ae883 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 18 Feb 2026 11:48:07 +0100 Subject: [PATCH 6/8] Remove login dokcer hub --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index f0cfeb8..6e1f094 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -60,8 +60,8 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Log in to Docker Hub - run: echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin +# - name: Log in to Docker Hub +# run: echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin - name: Build docker image run: docker build -t ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest -f docker/Dockerfile . From beb0e47402cca1f236126230ed06474a3601ae25 Mon Sep 17 00:00:00 2001 From: Voshiii Date: Wed, 18 Feb 2026 12:09:16 +0100 Subject: [PATCH 7/8] Added: alt login --- .github/workflows/ci-cd.yml | 9 ++++++--- helm/fastapi-gitops-starter/values.yaml | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6e1f094..93c2555 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -60,9 +60,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 -# - name: Log in to Docker Hub -# run: echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin - - name: Build docker image run: docker build -t ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest -f docker/Dockerfile . @@ -72,6 +69,12 @@ jobs: docker tag ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest \ ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:${{ github.ref_name }} + - name: Login to Container Registry + uses: docker/login-action@v1 + with: + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Push Docker image run: | docker push ${{ secrets.REGISTRY_USERNAME }}/fastapi-gitops-starter:latest diff --git a/helm/fastapi-gitops-starter/values.yaml b/helm/fastapi-gitops-starter/values.yaml index 20c08be..0d4219a 100644 --- a/helm/fastapi-gitops-starter/values.yaml +++ b/helm/fastapi-gitops-starter/values.yaml @@ -5,10 +5,10 @@ replicaCount: 1 image: - repository: ghcr.io/qcdis/fastapi-gitops-starter + repository: voshiii/fastapi-gitops-starter pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. - tag: "v0.4" + tag: latest registry: createImagePullSecret: true From 72a01f1dd9708fe6e7fd1e7e9eab9a7a72f4222e Mon Sep 17 00:00:00 2001 From: Voshiii Date: Fri, 27 Feb 2026 00:17:47 +0100 Subject: [PATCH 8/8] [fix] hpa k8s --- docker/Dockerfile | 2 +- helm/fastapi-gitops-starter/values.yaml | 27 +++++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 1ef04da..8e41440 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -9,7 +9,7 @@ COPY ../requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy application code -COPY ../app ./app/ +COPY app/ ./app/ # Expose port 8000 EXPOSE 8000 diff --git a/helm/fastapi-gitops-starter/values.yaml b/helm/fastapi-gitops-starter/values.yaml index 0d4219a..1290f90 100644 --- a/helm/fastapi-gitops-starter/values.yaml +++ b/helm/fastapi-gitops-starter/values.yaml @@ -6,18 +6,19 @@ replicaCount: 1 image: repository: voshiii/fastapi-gitops-starter - pullPolicy: IfNotPresent +# pullPolicy: IfNotPresent + pullPolicy: Never # Overrides the image tag whose default is the chart appVersion. tag: latest registry: - createImagePullSecret: true - secretName: image-pull-secret - server: ghcr.io + createImagePullSecret: false + secretName: "" + server: "" token: "" -imagePullSecrets: - - name: image-pull-secret +#imagePullSecrets: +# - name: image-pull-secret nameOverride: "" fullnameOverride: "" @@ -50,7 +51,7 @@ securityContext: service: type: ClusterIP - port: 80 + port: 8000 targetPort: 8000 annotations: {} @@ -79,8 +80,8 @@ resources: livenessProbe: httpGet: - path: /GitOps-Starter/health - port: http + path: /health #/GitOps-Starter/health + port: 8000 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 @@ -88,18 +89,18 @@ livenessProbe: readinessProbe: httpGet: - path: /GitOps-Starter/health - port: http + path: /health #/GitOps-Starter/health + port: 8000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 autoscaling: - enabled: false + enabled: true minReplicas: 2 maxReplicas: 10 - targetCPUUtilizationPercentage: 80 + targetCPUUtilizationPercentage: 10 targetMemoryUtilizationPercentage: 80 # Additional volumes on the output Deployment definition.