Skip to content
Open

Lab03 #2438

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
136 changes: 136 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: CI

on:
push:
branches:
- master
- lab*
paths:
- "app_python/**"
- ".github/workflows/python-ci.yml"
pull_request:
branches:
- master
- lab*
paths:
- "app_python/**"
- ".github/workflows/python-ci.yml"

concurrency:
group: python-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
test-and-lint:
name: Lint and Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
python-version: ["3.11", "3.12"]

defaults:
run:
working-directory: app_python

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: app_python/requirements.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run flake8
run: flake8 .

- name: Run tests with coverage
run: pytest --cov=. --cov-report=term --cov-report=xml --cov-fail-under=70

- name: Upload coverage to Codecov
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
files: ./app_python/coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}

docker-build-and-push:
name: Build and Push Docker Image
needs: test-and-lint
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'

env:
IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set CalVer version
id: set-version
run: echo "VERSION=$(date +'%Y.%m.%d')" >> "$GITHUB_ENV"

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./app_python
push: true
tags: |
${{ env.IMAGE_NAME }}:${{ env.VERSION }}
${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max

security-scan:
name: Snyk Security Scan
needs: test-and-lint
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python (for dependency resolution)
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
working-directory: app_python
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Set up Snyk CLI
uses: snyk/actions/setup@master

- name: Run Snyk to check for vulnerabilities
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: >
snyk test
--file=app_python/requirements.txt
--package-manager=pip
--severity-threshold=medium
--sarif-file-output=snyk.sarif



20 changes: 20 additions & 0 deletions app_python/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
__pycache__/
*.py[cod]
*.pyo
*.pyd

venv/
.venv/

.git
.gitignore

.vscode/
.idea/

tests/
docs/

*.log
*.md

27 changes: 27 additions & 0 deletions app_python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/
*.log

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Testing
.pytest_cache/
.coverage
htmlcov/

31 changes: 31 additions & 0 deletions app_python/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM python:3.13-slim

# Prevent Python from writing .pyc files and enable unbuffered logs
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

# Create a non-root user and group
RUN addgroup --system app && adduser --system --ingroup app app

# Set working directory
WORKDIR /app

# Install dependencies first (better layer caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy only the application code needed at runtime
COPY app.py .

# Document the port the app listens on
EXPOSE 5000

# Switch to the non-root user
USER app

# Default environment (can be overridden at runtime)
ENV HOST=0.0.0.0 \
PORT=5000

# Start the Flask application
CMD ["python", "app.py"]
Loading