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

on:
push:
branches: [ master, lab03 ]
paths:
- 'app_python/**'
- '.github/workflows/python-ci.yml'
pull_request:
paths:
- 'app_python/**'

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

steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: "pip"

- name: Install dependencies
run: |
pip install -r app_python/requirements.txt
pip install -r app_python/requirements-dev.txt

- name: Lint
run: ruff check app_python

- name: Run tests
run: pytest app_python/tests

- name: Generate version
run: echo "VERSION=$(date +%Y.%m.%d)" >> $GITHUB_ENV

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

- name: Snyk Scan
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: snyk test --file=app_python/requirements.txt

- name: Build and Push Docker Image
uses: docker/build-push-action@v6
with:
context: ./app_python
push: true
tags: |
maksimmenshikh/devops-info-service:${{ env.VERSION }}
maksimmenshikh/devops-info-service:latest
8 changes: 8 additions & 0 deletions app_python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,11 @@ docker run -p 5000:5000 maksimmenshikh/devops-info-service
### Pull from Docker Hub

docker pull maksimmenshikh/devops-info-service

## Running Tests

cd app_python
pip install -r requirements-dev.txt
pytest -v

![CI](https://github.com/MMenshikh/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg)
93 changes: 93 additions & 0 deletions app_python/docs/LAB03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# LAB03 --- CI/CD Pipeline with GitHub Actions

## CI/CD Practices Applied

### Automated Builds

Docker image is automatically built on push and pull requests using
GitHub Actions.

### Secure Secrets Management

Sensitive data stored in GitHub Repository Secrets instead of hardcoding
credentials.

### Container Security Scanning

Snyk integrated into pipeline to scan Docker image for vulnerabilities.

### Continuous Delivery

Docker image automatically pushed to DockerHub after successful pipeline
execution.

------------------------------------------------------------------------

## Pipeline Information & Decisions

CI Platform: GitHub Actions\
Container Registry: DockerHub\
Security Scanner: Snyk

Triggers: - push to main - pull requests

Pipeline Stages: 1. Repository checkout 2. Docker image build 3.
Security scan with Snyk 4. DockerHub login 5. Image push to registry

------------------------------------------------------------------------

## Workflow Execution Process

### Automatic Trigger

Pipeline runs when:

- code is pushed
- pull request is created

### Build Stage

Docker image built using:

docker build -t devops-info-service .

### Security Scan

Snyk scans Docker image for known vulnerabilities before publishing.

### Push Stage

Image pushed to:

maksimmenshikh/devops-info-service

------------------------------------------------------------------------

## Technical Analysis

Automated CI reduces manual deployment steps and human error.

Secrets stored in GitHub prevent credential exposure in repository code.

Security scanning ensures vulnerabilities are detected early in
development.

Automated publishing guarantees consistent container versions.

------------------------------------------------------------------------

## Challenges & Solutions

### Missing Secrets

Pipeline failed due to missing repository secrets.\
Solved by adding DOCKERHUB_TOKEN, DOCKERHUB_USERNAME and SNYK_TOKEN.

### Docker Authentication Failure

Fixed by generating DockerHub access token and configuring
docker/login-action.

### Failed Security Scan

Resolved by rebuilding image and ensuring dependencies were up to date.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app_python/requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pytest==8.3.5
pytest-cov==5.0.0
ruff==0.9.0
40 changes: 40 additions & 0 deletions app_python/tests/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest
from app import app


@pytest.fixture
def client():
app.config["TESTING"] = True
with app.test_client() as client:
yield client


def test_index_ok(client):
response = client.get("/")
assert response.status_code == 200

data = response.get_json()

assert "service" in data
assert "system" in data
assert "runtime" in data
assert "request" in data
assert "endpoints" in data


def test_health_ok(client):
response = client.get("/health")
assert response.status_code == 200

data = response.get_json()
assert data["status"] == "healthy"
assert "timestamp" in data
assert "uptime_seconds" in data


def test_404(client):
response = client.get("/unknown")
assert response.status_code == 404

data = response.get_json()
assert data["error"] == "Not Found"
Loading