Skip to content

Commit d31f9ad

Browse files
committed
Refactors versioning, improves Docker logging, and enables script sanitization.
1 parent 85678fc commit d31f9ad

File tree

3 files changed

+62
-59
lines changed

3 files changed

+62
-59
lines changed

.github/workflows/release.yml

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -201,62 +201,39 @@ jobs:
201201
publish-docker:
202202
name: Publish Docker Image
203203
runs-on: ubuntu-latest
204-
needs: [release] # Depend on 'release' job to ensure artifacts are uploaded and version is stable
204+
needs: [release]
205+
205206
steps:
206207
- name: Checkout repository
207208
uses: actions/checkout@v4
208209
with:
209-
fetch-depth: 0 # Required for setuptools-scm to determine the version
210-
211-
- name: Setup Python
212-
uses: actions/setup-python@v5
213-
with:
214-
python-version: '3.x' # Use a recent Python version
215-
216-
- name: Install setuptools-scm
217-
run: pip install setuptools-scm
210+
fetch-depth: 0
218211

219-
- name: Generate _version.py
220-
run: |
221-
python -c "import setuptools_scm; \
222-
import os; \
223-
# Get the version from setuptools_scm, using the current directory as root \
224-
# fallback_version is used if setuptools_scm cannot determine the version (e.g., no .git) \
225-
version = setuptools_scm.get_version(root='.', fallback_version='0.0.0+unknown'); \
226-
# Ensure the version string is clean for Python (remove leading 'v' if present) \
227-
if version.startswith('v'): version = version[1:]; \
228-
# Write the version to _version.py \
229-
with open('_version.py', 'w') as f: f.write(f\"__version__ = '{version}'\\n\"); \
230-
print(f\"Generated _version.py with __version__ = '{version}'\")"
231-
232-
- name: Get version from _version.py
233-
id: get_version
212+
- name: Extract version from tag
213+
id: version
234214
run: |
235-
# Read the __version__ variable from the generated _version.py
236-
# Add current directory to PYTHONPATH to allow importing _version.py
237-
VERSION=$(PYTHONPATH=. python -c "import _version; print(_version.__version__)")
238-
# Remove leading 'v' if present (e.g., v1.0.0 -> 1.0.0)
239-
VERSION="${VERSION#v}"
240-
# Extract major version (e.g., 1.0.0 -> 1)
241-
MAJOR_VERSION=$(echo "$VERSION" | cut -d. -f1)
215+
RAW="${GITHUB_REF_NAME}"
216+
VERSION="${RAW#v}"
217+
MAJOR="${VERSION%%.*}"
242218
echo "VERSION=$VERSION" >> $GITHUB_ENV
243-
echo "MAJOR_VERSION=$MAJOR_VERSION" >> $GITHUB_ENV
244-
echo "Extracted VERSION: $VERSION"
245-
echo "Extracted MAJOR_VERSION: $MAJOR_VERSION"
219+
echo "MAJOR_VERSION=$MAJOR" >> $GITHUB_ENV
220+
echo "Version = $VERSION"
221+
echo "Major = $MAJOR"
246222
247223
- name: Log in to Docker Hub
248224
uses: docker/login-action@v3
249225
with:
250226
username: ${{ secrets.DOCKER_USERNAME }}
251227
password: ${{ secrets.DOCKER_PASSWORD }}
252228

253-
# --- Build and push FULL image (with WhisperX) ---
254229
- name: Build and push FULL Docker image
255230
uses: docker/build-push-action@v5
256231
with:
257232
context: .
258233
push: true
259-
target: with_whisperx # Assuming this is the target for the full version
234+
target: with_whisperx
235+
build-args: |
236+
VERSION=${{ env.VERSION }}
260237
tags: |
261238
gandulf78/podcast_generator:${{ env.VERSION }}
262239
gandulf78/podcast_generator:${{ env.MAJOR_VERSION }}
@@ -265,13 +242,14 @@ jobs:
265242
org.opencontainers.image.source=${{ github.event.repository.html_url }}
266243
org.opencontainers.image.version=${{ env.VERSION }}
267244
268-
# --- Build and push LIGHT image (without WhisperX) ---
269245
- name: Build and push LIGHT Docker image
270246
uses: docker/build-push-action@v5
271247
with:
272248
context: .
273249
push: true
274-
target: without_whisperx # Assuming this is the target for the light version
250+
target: without_whisperx
251+
build-args: |
252+
VERSION=${{ env.VERSION }}
275253
tags: |
276254
gandulf78/podcast_generator:${{ env.VERSION }}-light
277255
gandulf78/podcast_generator:${{ env.MAJOR_VERSION }}-light

Dockerfile

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,68 @@
1-
# --- Stage 1: Base dependencies ---
1+
# ================================
2+
# Stage 1: Base dependencies
3+
# ================================
24
FROM python:3.11-slim-bookworm AS base
35

4-
# Set the working directory in the container
6+
# Workdir
57
WORKDIR /app
68

7-
# Install FFmpeg (required for audio processing)
8-
# Also install git for whisperx dependencies
9+
# Avoid writing .pyc files and enable immediate flush
10+
ENV PYTHONDONTWRITEBYTECODE=1
11+
ENV PYTHONUNBUFFERED=1
12+
13+
# Install system deps (ffmpeg required)
914
RUN apt-get update && apt-get install -y --no-install-recommends \
1015
ffmpeg \
1116
git \
12-
&& rm -rf /var/lib/apt/lists/*
17+
&& rm -rf /var/lib/apt/lists/* \
18+
&& apt-get purge -y git
1319

14-
# Copy the core requirements file
20+
# Copy requirements
1521
COPY requirements.txt .
1622

17-
# Install core dependencies
23+
# Install Python dependencies (core only — no WhisperX)
1824
RUN pip install --no-cache-dir -r requirements.txt
1925

20-
# Copy the rest of the application code
26+
# Copy entire app
2127
COPY . .
2228

23-
# --- Stage 2: Build with WhisperX support ---
29+
# Inject version (default "dev"; overwritten at build time)
30+
ARG VERSION="dev"
31+
RUN echo "{\"version\": \"${VERSION}\"}" > version.json
32+
33+
34+
# ================================
35+
# Stage 2: Image WITH WhisperX
36+
# ================================
2437
FROM base AS with_whisperx
2538

26-
# Install PyTorch (CPU-only for broader compatibility in Docker) and torchaudio
27-
# Then install whisperx
39+
# Install CPU PyTorch + WhisperX
2840
RUN pip install --no-cache-dir \
2941
torch==2.2.2+cpu \
3042
torchaudio==2.2.2+cpu \
3143
-f https://download.pytorch.org/whl/torch_stable.html \
3244
&& pip install --no-cache-dir whisperx==3.1.1
3345

34-
# Set environment variable to enable demo features
46+
# Indicate WhisperX is available
3547
ENV DEMO_AVAILABLE=1
3648

37-
# Expose the port that Gunicorn will listen on
49+
# Expose API port
3850
EXPOSE 8000
3951

40-
# Run gunicorn to serve the Flask application
52+
# Start backend
4153
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
4254

43-
# --- Stage 3: Build without WhisperX support ---
55+
56+
# ================================
57+
# Stage 3: Image WITHOUT WhisperX
58+
# ================================
4459
FROM base AS without_whisperx
4560

46-
# Set environment variable to disable demo features
61+
# WhisperX disabled
4762
ENV DEMO_AVAILABLE=0
4863

49-
# Expose the port that Gunicorn will listen on
64+
# Expose API port
5065
EXPOSE 8000
5166

52-
# Run gunicorn to serve the Flask application
53-
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
67+
# Start backend
68+
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

app.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import re
1414
import uuid
1515
import threading
16+
import json
17+
from flask import jsonify
1618

1719
# --- App Initialization ---
1820
app = Flask(__name__)
@@ -74,7 +76,15 @@ def get_asset(filename):
7476

7577
@app.route('/api/about', methods=['GET'])
7678
def get_about_info():
77-
return jsonify({'version': __version__, 'license': LICENSE_TEXT})
79+
return jsonify({'version': version(), 'license': LICENSE_TEXT})
80+
81+
def version():
82+
try:
83+
with open("version.json") as f:
84+
data = json.load(f)
85+
return data.get("version", "unknown")
86+
except Exception:
87+
return "unknown"
7888

7989
@app.route('/api/status', methods=['GET'])
8090
def get_status():

0 commit comments

Comments
 (0)