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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ ENV/
output/
.coverage

# Build artifacts
git_info.json

# Django
*.log
# db.sqlite3
Expand Down
18 changes: 13 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
# Use the official Python runtime image
FROM python:3.13-slim

# Git info passed as build args (no .git directory needed)
ARG GIT_COMMIT_SHA=""
ARG GIT_COMMIT_MSG=""
ARG GIT_BRANCH=""

# Create the app directory
RUN mkdir /app

# Set the working directory inside the container
WORKDIR /app

# Set environment variables
# Set environment variables
# Prevents Python from writing pyc files to disk
ENV PYTHONDONTWRITEBYTECODE=1
#Prevents Python from buffering stdout and stderr
ENV PYTHONUNBUFFERED=1
ENV PYTHONUNBUFFERED=1

# Install system dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends ffmpeg yt-dlp just sqlite3 && \
rm -rf /var/lib/apt/lists/*

# Upgrade pip
RUN pip install --upgrade pip
RUN pip install --upgrade pip

# Copy the Django project and install dependencies
COPY requirements.txt /app/

# run this command to install all dependencies
# run this command to install all dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the Django project to the container
COPY . /app/

# Write git info (outside /app so volume mounts don't hide it)
RUN printf '{"commit_sha": "%s", "commit_message": "%s", "branch": "%s"}\n' \
"$GIT_COMMIT_SHA" "$GIT_COMMIT_MSG" "$GIT_BRANCH" > /etc/git_info.json

# Expose the Django port
EXPOSE 8000

Expand Down
14 changes: 12 additions & 2 deletions docker-compose.coolify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ services:
- web

web:
build: .
build:
context: .
args:
GIT_COMMIT_SHA: ${GIT_COMMIT_SHA:-}
GIT_COMMIT_MSG: ${GIT_COMMIT_MSG:-}
GIT_BRANCH: ${GIT_BRANCH:-}
container_name: stashcast_web
environment:
STASHCAST_DATA_DIR: /app/data_docker
Expand All @@ -23,7 +28,12 @@ services:
- ./data_docker:/app/data_docker

worker:
build: .
build:
context: .
args:
GIT_COMMIT_SHA: ${GIT_COMMIT_SHA:-}
GIT_COMMIT_MSG: ${GIT_COMMIT_MSG:-}
GIT_BRANCH: ${GIT_BRANCH:-}
container_name: stashcast_worker
command: python manage.py run_huey
hostname: worker
Expand Down
14 changes: 12 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ services:
- web

web:
build: .
build:
context: .
args:
GIT_COMMIT_SHA: ${GIT_COMMIT_SHA:-}
GIT_COMMIT_MSG: ${GIT_COMMIT_MSG:-}
GIT_BRANCH: ${GIT_BRANCH:-}
container_name: stashcast_web
environment:
STASHCAST_DATA_DIR: /app/data_docker
Expand All @@ -23,7 +28,12 @@ services:
- ./data_docker:/app/data_docker

worker:
build: .
build:
context: .
args:
GIT_COMMIT_SHA: ${GIT_COMMIT_SHA:-}
GIT_COMMIT_MSG: ${GIT_COMMIT_MSG:-}
GIT_BRANCH: ${GIT_BRANCH:-}
container_name: stashcast_worker
command: python manage.py run_huey
depends_on:
Expand Down
59 changes: 59 additions & 0 deletions media/apps.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,72 @@
import json
import logging
import subprocess
from pathlib import Path

from django.apps import AppConfig
from django.utils import timezone

logger = logging.getLogger(__name__)


DEPLOY_TIME = timezone.now()


def _get_git_info():
"""Capture git info at startup for display on the About page.

Tries two sources in order:
1. git_info.json written during Docker build (for container deploys)
2. Live git commands (for local development)
"""
info = {'commit_sha': '', 'commit_sha_short': '', 'commit_message': '', 'branch': ''}

# Try reading from the build-time JSON file (Docker deployments)
# Check /etc first (survives volume mounts), then app dir (local builds)
for json_path in [Path('/etc/git_info.json'), Path(__file__).resolve().parent.parent / 'git_info.json']:
try:
data = json.loads(json_path.read_text())
if data.get('commit_sha'):
info['commit_sha'] = data['commit_sha']
info['commit_sha_short'] = data['commit_sha'][:7]
info['commit_message'] = data.get('commit_message', '')
info['branch'] = data.get('branch', '')
return info
except Exception:
pass

# Fall back to live git commands (local development)
try:
info['commit_sha'] = subprocess.check_output(
['git', 'rev-parse', 'HEAD'], stderr=subprocess.DEVNULL, text=True
).strip()
info['commit_sha_short'] = info['commit_sha'][:7]
info['commit_message'] = subprocess.check_output(
['git', 'log', '-1', '--pretty=%s'], stderr=subprocess.DEVNULL, text=True
).strip()
info['branch'] = subprocess.check_output(
['git', 'rev-parse', '--abbrev-ref', 'HEAD'], stderr=subprocess.DEVNULL, text=True
).strip()
except Exception:
pass
return info


GIT_INFO = _get_git_info()


class MediaConfig(AppConfig):
name = 'media'
default_auto_field = 'django.db.models.BigAutoField'

def ready(self):
"""Import signals when the app is ready"""
if GIT_INFO['commit_sha_short']:
logger.info(
"StashCast commit=%s branch=%s message=%s",
GIT_INFO['commit_sha_short'],
GIT_INFO.get('branch', ''),
GIT_INFO.get('commit_message', ''),
)
else:
logger.info("StashCast git info not available")
9 changes: 9 additions & 0 deletions media/templates/admin/preferences.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ <h2>{% trans "About" %}</h2>
<span id="deploy-time" data-utc="{{ deploy_time|date:'c' }}">
{{ deploy_time|timesince }} {% trans "ago" %} ({{ deploy_time }})
</span>
{% if git_info.commit_sha_short %}
&mdash;
<a href="https://github.com/jonocodes/stashcast/commit/{{ git_info.commit_sha }}" target="_blank" rel="noopener" title="{{ git_info.commit_message }}">
<code>{{ git_info.commit_sha_short }}</code>
</a>
{% if git_info.branch %}
on <code>{{ git_info.branch }}</code>
{% endif %}
{% endif %}
<script>
(function() {
var el = document.getElementById('deploy-time');
Expand Down
3 changes: 2 additions & 1 deletion media/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ def preferences_view(request):
# Episode limit
max_episodes = settings.STASHCAST_MAX_EPISODES

from media.apps import DEPLOY_TIME
from media.apps import DEPLOY_TIME, GIT_INFO

context = {
**admin.site.each_context(request),
Expand All @@ -992,6 +992,7 @@ def preferences_view(request):
'total_storage_bytes': total_storage_bytes,
'max_episodes': max_episodes,
'deploy_time': DEPLOY_TIME,
'git_info': GIT_INFO,
}

return render(request, 'admin/preferences.html', context)
Expand Down