Skip to content
This repository was archived by the owner on Jan 12, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
558159b
Updated home route with custom welcome message
TharushiMaduhansi Jul 28, 2025
fea8414
Add GitHub Actions CI workflow
TharushiMaduhansi Jul 28, 2025
145ab35
Delete .github/workflows/codeql-analysis.yml
Nethma-k Jul 28, 2025
8e1de58
Add GitHub Actions CI workflow
TharushiMaduhansi Jul 28, 2025
7f24990
Update ci.yml
Nethma-k Jul 28, 2025
806be3a
Fix CI workflow syntax
TharushiMaduhansi Jul 28, 2025
e51315d
Fix GitHub Actions workflow syntax
TharushiMaduhansi Jul 28, 2025
23e5376
Update Python version to 3.9.17 in GitHub Actions workflow
TharushiMaduhansi Jul 28, 2025
7e0c5d1
Create google-cloudrun-docker.yml
Nethma-k Jul 28, 2025
9521a61
Delete .github/workflows/.github/workflows directory
Nethma-k Jul 28, 2025
fc3f1f1
Create cloudrunner
Nethma-k Jul 28, 2025
f60715b
Delete .github/workflows/cloudrunner
Nethma-k Jul 28, 2025
1e5c3e9
Create cloudrunner.yml
Nethma-k Jul 28, 2025
8c143e7
Update ci.yml
Nethma-k Jul 28, 2025
f44ce7e
Update requirements.txt
Nethma-k Jul 28, 2025
9535625
Update requirements.txt
Nethma-k Jul 28, 2025
57858c3
Update requirements.txt
Nethma-k Jul 28, 2025
31c0654
Update cloudrunner.yml
Nethma-k Jul 28, 2025
aa27610
Update Dockerfile
Nethma-k Jul 28, 2025
8e11883
Update Dockerfile
Nethma-k Jul 28, 2025
6535232
Create entrypoint.sh
Nethma-k Jul 28, 2025
b424268
Update README.md
Nethma-k Jul 28, 2025
29a6810
Update entrypoint.sh
Nethma-k Jul 28, 2025
ce56fb8
Create cd.yml
heittre Jul 28, 2025
ccab56b
Update Dockerfile
Nethma-k Jul 28, 2025
6a22c0f
Create cd.yml
heittre Jul 28, 2025
0a6af15
Update Dockerfile
Nethma-k Jul 28, 2025
3cea696
Create test.yml
heittre Jul 28, 2025
2aef03e
Update Dockerfile
Nethma-k Jul 28, 2025
943df97
add changes
heittre Jul 28, 2025
01047ba
add changes
heittre Jul 28, 2025
e16a073
Update README.md
heittre Jul 28, 2025
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
57 changes: 57 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Deploy Flask App to VM

on:
push:
branches:
- main # orr your default branch

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

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

- name: Install dependencies (for lint/test, optional)
run: |
python -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

- name: Copy files to VM
uses: appleboy/scp-action@v0.1.5

Check warning on line 29 in .github/workflows/cd.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.github/workflows/cd.yml#L29

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
port: 22
source: "."
target: "/home/${{ secrets.VM_USER }}/ci-cd-tutorial-sample-app"

- name: Run deploy commands on VM
uses: appleboy/ssh-action@v0.1.6

Check warning on line 39 in .github/workflows/cd.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.github/workflows/cd.yml#L39

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
port: 22
script: |
cd ~/ci-cd-tutorial-sample-app
# Activate virtual environment or create if missing
if [ ! -d "venv" ]; then
python3 -m venv venv
fi
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

# Restart Gunicorn (adjust service name or command as needed)
pkill gunicorn || true
nohup gunicorn --bind 0.0.0.0:8000 app:app > gunicorn.log 2>&1 &
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Python Flask CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

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

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9.17

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

- name: Run tests
run: python -m pytest # Change this line
49 changes: 49 additions & 0 deletions .github/workflows/cloudrunner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: 'Build and Deploy to Cloud Run'

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

env:
PROJECT_ID: 'thermal-hour-467308-u4'
GAR_NAME: 'gh-demo'
REGION: 'us-central1'
SERVICE: 'gitactionnew'

jobs:
deploy:
runs-on: ubuntu-latest

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

- name: 'Authenticate to Google Cloud with SA Key'
uses: google-github-actions/auth@v2

Check warning on line 24 in .github/workflows/cloudrunner.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.github/workflows/cloudrunner.yml#L24

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
credentials_json: '${{ secrets.ABC }}'

- name: 'Set up gcloud CLI'
uses: google-github-actions/setup-gcloud@v2

Check warning on line 29 in .github/workflows/cloudrunner.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.github/workflows/cloudrunner.yml#L29

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.

- name: 'Docker Auth'
run: gcloud auth configure-docker "${{ env.REGION }}-docker.pkg.dev"

- name: 'Build and Push Docker Image'
run: |
IMAGE="${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.GAR_NAME }}/${{ env.SERVICE }}:${{ github.sha }}"
docker build -t "$IMAGE" .
docker push "$IMAGE"

- name: 'Deploy to Cloud Run'
id: deploy
uses: google-github-actions/deploy-cloudrun@v2

Check warning on line 42 in .github/workflows/cloudrunner.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

.github/workflows/cloudrunner.yml#L42

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
service: ${{ env.SERVICE }}
region: ${{ env.REGION }}
image: "${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.GAR_NAME }}/${{ env.SERVICE }}:${{ github.sha }}"

- name: Show Deployed URL
run: echo ${{ steps.deploy.outputs.url }}
67 changes: 0 additions & 67 deletions .github/workflows/codeql-analysis.yml

This file was deleted.

12 changes: 12 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Test Workflow

on:
push:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Echo message
run: echo "✅ GitHub Actions are working!"
46 changes: 33 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
FROM ubuntu:18.04
# Use the official lightweight Python image.
FROM python:3.11-slim

RUN apt-get update && \
apt-get -y upgrade && \
DEBIAN_FRONTEND=noninteractive apt-get install -yq libpq-dev gcc python3.8 python3-pip && \
apt-get clean
# Set environment variables for Python in Docker
# Prevents Python from writing .pyc files
ENV PYTHONDONTWRITEBYTECODE=1
# Ensures Python output is sent immediately to the terminal
ENV PYTHONUNBUFFERED=1
# Add /app to PYTHONPATH so Python can find your 'app' package
ENV PYTHONPATH=/app:$PYTHONPATH

WORKDIR /sample-app
# Set the working directory inside the container
WORKDIR /app

COPY . /sample-app/
# Expose port 8080. Cloud Run typically expects services to listen on this port.
EXPOSE 8080

RUN pip3 install -r requirements.txt && \
pip3 install -r requirements-server.txt
# Install dependencies
# Copy requirements files first to leverage Docker's caching.
COPY requirements.txt .
COPY requirements-server.txt .

ENV LC_ALL="C.UTF-8"
ENV LANG="C.UTF-8"
# Install Python dependencies.
RUN pip install --no-cache-dir --upgrade pip && \

Check warning on line 24 in Dockerfile

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Dockerfile#L24

Pin versions in pip. Instead of `pip install <package>` use `pip install <package>==<version>` or `pip install --requirement <requirements file>`
pip install -r requirements.txt && \
pip install -r requirements-server.txt

EXPOSE 8000/tcp
# Copy the rest of your application code into the container
COPY . .

CMD ["/bin/sh", "-c", "flask db upgrade && gunicorn app:app -b 0.0.0.0:8000"]
# Copy the entrypoint script and make it executable
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Use the entrypoint script.
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

# The CMD provides default arguments to the ENTRYPOINT script.
# Since Gunicorn is started by entrypoint.sh, this can be empty or used for further arguments.
CMD []
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

# CD/CI Tutorial Sample Application

## Description
## Descriptio

This sample Python REST API application was written for a tutorial on implementing Continuous Integration and Delivery pipelines.
This sample Python REST API application was written for a tutorial on implementing Continuous Integration and Delivery pipelines

It demonstrates how to:

Expand Down
9 changes: 6 additions & 3 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from flask import json, jsonify
from flask import jsonify
from app import app
from app import db
from app.models import Menu

@app.route('/')
def home():
return jsonify({ "status": "ok" })
return jsonify({
"message": "Welcome to Tharushi's CI/CD demo app 🎉",
"status": "ok"
})

@app.route('/menu')
def menu():
Expand All @@ -16,4 +19,4 @@ def menu():
else:
body = { "error": "Sorry, the service is not available today." }
status = 404
return jsonify(body), status
return jsonify(body), status
57 changes: 57 additions & 0 deletions cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Deploy Flask App to VM

on:
push:
branches:
- main # or your default branch

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

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

- name: Install dependencies (for lint/test, optional)
run: |
python -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

- name: Copy files to VM
uses: appleboy/scp-action@v0.1.5

Check warning on line 29 in cd.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

cd.yml#L29

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
port: 22
source: "."
target: "/home/${{ secrets.VM_USER }}/ci-cd-tutorial-sample-app"

- name: Run deploy commands on VM
uses: appleboy/ssh-action@v0.1.6

Check warning on line 39 in cd.yml

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

cd.yml#L39

An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
port: 22
script: |
cd ~/ci-cd-tutorial-sample-app
# Activate virtual environment or create if missing
if [ ! -d "venv" ]; then
python3 -m venv venv
fi
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

# Restart Gunicorn (adjust service name or command as needed)
pkill gunicorn || true
nohup gunicorn --bind 0.0.0.0:8000 app:app > gunicorn.log 2>&1 &
25 changes: 25 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh

echo "Starting entrypoint script..."

# Set FLASK_APP to 'app' (the package name).
# This is crucial for Flask CLI commands and Gunicorn to find your application instance.
export FLASK_APP=app

echo "Running database migrations..."
# Execute migrations. Redirecting stderr to stdout (2>&1) ensures errors are logged to Cloud Logging.
# The 'set -e' (often implied by shebang or default shell behavior) will cause the script to exit
# immediately if 'flask db upgrade' fails, which is desired for failed deployments.
if flask db upgrade 2>&1; then
echo "Database migrations completed successfully."
else
echo "ERROR: Database migrations failed!"
# Exit with a non-zero status to indicate failure to Cloud Run.
exit 1
fi

echo "Starting Gunicorn server..."
# Cloud Run injects the PORT environment variable (defaulting to 8080).
# Ensure Gunicorn binds to 0.0.0.0 and uses this PORT variable.
# The ${PORT:-8080} syntax provides a fallback to 8080 if PORT isn't set (e.g., for local testing).
exec gunicorn app:app -b 0.0.0.0:${PORT:-8080}

Check warning on line 25 in entrypoint.sh

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

entrypoint.sh#L25

Double quote to prevent globbing and word splitting.
Loading