Skip to content

Commit 08bde8f

Browse files
committed
feat: selective merge from main
- Keep our CI/CD workflows and uv-based setup - Adopt Dockerfile improvements from main (better cleanup, security) - Remove poetry.lock (we use uv) - Add renovate.json5 for automated dependency updates - Update other minor improvements from main branch
2 parents 6502e1e + d8f719f commit 08bde8f

File tree

6 files changed

+122
-65
lines changed

6 files changed

+122
-65
lines changed

.github/renovate.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

.github/renovate.json5

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3+
"extends": [
4+
"config:best-practices"
5+
],
6+
"schedule": [
7+
"* */12 * * *"
8+
],
9+
"ignoreDeps": [
10+
"basedpyright" // see pyproject.toml
11+
],
12+
"lockFileMaintenance": {
13+
"enabled": true,
14+
"automerge": true
15+
},
16+
"packageRules": [
17+
{
18+
// these will fail tests if they are broken
19+
// idk if this works with python, either way it doesnt matter
20+
//"matchDepTypes": [
21+
// "devDependencies"
22+
//],
23+
"matchPackageNames": [
24+
"pre-commit",
25+
"ruff",
26+
"poetry",
27+
"pytest"
28+
],
29+
"automerge": true
30+
},
31+
{
32+
// no breaking changes
33+
"matchUpdateTypes": [
34+
"minor",
35+
"patch"
36+
],
37+
"matchCurrentVersion": "!/^0/",
38+
"automerge": true
39+
}
40+
]
41+
}

.mise.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[tools]
2-
python = "3.13.5"
2+
python = "3.13.7"

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.13.5
1+
3.13.7

Dockerfile

Lines changed: 78 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
# Size Impact: ~150MB (Python slim + runtime deps)
4444
# ==============================================================================
4545

46-
FROM python:3.13.5-slim@sha256:4c2cf9917bd1cbacc5e9b07320025bdb7cdf2df7b0ceaccb55e9dd7e30987419 AS base
46+
FROM python:3.13.7-slim@sha256:27f90d79cc85e9b7b2560063ef44fa0e9eaae7a7c3f5a9f74563065c5477cc24 AS base
4747

4848
# OCI Labels for container metadata and registry compliance
4949
# These labels provide important metadata for container registries and tools
@@ -81,13 +81,12 @@ RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
8181
RUN apt-get update && \
8282
apt-get upgrade -y && \
8383
apt-get install -y --no-install-recommends --no-install-suggests \
84-
ffmpeg=7:5.1.6-0+deb12u1 \
85-
git=1:2.39.5-0+deb12u2 \
86-
libcairo2=1.16.0-7 \
87-
libgdk-pixbuf2.0-0=2.40.2-2 \
88-
libpango1.0-0=1.50.12+ds-1 \
89-
libpangocairo-1.0-0=1.50.12+ds-1 \
90-
shared-mime-info=2.2-1 \
84+
git=1:2.47.2-0.2 \
85+
libcairo2=1.18.4-1+b1 \
86+
libgdk-pixbuf-2.0-0=2.42.12+dfsg-4 \
87+
libpango-1.0-0=1.56.3-1 \
88+
libpangocairo-1.0-0=1.56.3-1 \
89+
shared-mime-info=2.4-5+b2 \
9190
# Cleanup package manager caches to reduce layer size
9291
&& apt-get clean \
9392
&& rm -rf /var/lib/apt/lists/*
@@ -108,7 +107,7 @@ ENV PYTHONUNBUFFERED=1 \
108107
# ==============================================================================
109108
# BUILD STAGE - Development Tools and Dependency Installation
110109
# ==============================================================================
111-
# Purpose: Installs build tools, Uv, and application dependencies
110+
# Purpose: Installs build tools, Poetry, and application dependencies
112111
# Contains: Compilers, headers, build tools, complete Python environment
113112
# Size Impact: ~1.3GB (includes all build dependencies and Python packages)
114113
# ==============================================================================
@@ -122,21 +121,37 @@ RUN apt-get update && \
122121
apt-get upgrade -y && \
123122
apt-get install -y --no-install-recommends \
124123
# GCC compiler and build essentials for native extensions
125-
build-essential=12.9 \
124+
build-essential=12.12 \
126125
# Additional utilities required by some Python packages
127-
findutils=4.9.0-4 \
126+
findutils=4.10.0-3 \
128127
# Development headers for graphics libraries
129-
libcairo2-dev=1.16.0-7 \
128+
libcairo2-dev=1.18.4-1+b1 \
130129
# Foreign Function Interface library for Python extensions
131-
libffi-dev=3.4.4-1 \
130+
libffi8=3.4.8-2 \
132131
# Cleanup to reduce intermediate layer size
133132
&& apt-get clean \
134133
&& rm -rf /var/lib/apt/lists/*
135134

136-
ENV UV_VERSION=0.8.0
135+
# Poetry configuration for dependency management
136+
# These settings optimize Poetry for containerized builds
137137

138-
# Install Uv using pip
139-
RUN pip install uv==$UV_VERSION
138+
# POETRY_NO_INTERACTION=1 : Disables interactive prompts for CI/CD
139+
# POETRY_VIRTUALENVS_CREATE=1 : Ensures virtual environment creation
140+
# POETRY_VIRTUALENVS_IN_PROJECT=1: Creates .venv in project directory
141+
# POETRY_CACHE_DIR=/tmp/poetry_cache: Uses temporary directory for cache
142+
# POETRY_INSTALLER_PARALLEL=true : Enables parallel package installation
143+
144+
ENV POETRY_VERSION=2.1.1 \
145+
POETRY_NO_INTERACTION=1 \
146+
POETRY_VIRTUALENVS_CREATE=1 \
147+
POETRY_VIRTUALENVS_IN_PROJECT=1 \
148+
POETRY_CACHE_DIR=/tmp/poetry_cache \
149+
POETRY_INSTALLER_PARALLEL=true
150+
151+
# Install Poetry using pip with BuildKit cache mount for efficiency
152+
# Cache mount prevents re-downloading Poetry on subsequent builds
153+
RUN --mount=type=cache,target=/root/.cache \
154+
pip install poetry==$POETRY_VERSION
140155

141156
# Set working directory for all subsequent operations
142157
WORKDIR /app
@@ -148,13 +163,15 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
148163
# Copy dependency files first for optimal Docker layer caching
149164
# Changes to these files will invalidate subsequent layers
150165
# OPTIMIZATION: This pattern maximizes cache hits during development
151-
COPY pyproject.toml uv.lock ./
166+
COPY pyproject.toml poetry.lock ./
152167

153-
# Install dependencies
154-
RUN --mount=type=cache,target=/root/.cache/uv \
155-
--mount=type=bind,source=uv.lock,target=uv.lock \
156-
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
157-
uv sync --locked --no-install-project
168+
# Install Python dependencies using Poetry
169+
# PERFORMANCE: Cache mount speeds up subsequent builds
170+
# SECURITY: --only main excludes development dependencies from production
171+
# NOTE: Install dependencies only first, package itself will be installed later with git context
172+
RUN --mount=type=cache,target=$POETRY_CACHE_DIR \
173+
--mount=type=cache,target=/root/.cache/pip \
174+
poetry install --only main --no-root --no-directory
158175

159176
# Copy application files in order of change frequency (Docker layer optimization)
160177
# STRATEGY: Files that change less frequently are copied first to maximize cache reuse
@@ -163,16 +180,13 @@ RUN --mount=type=cache,target=/root/.cache/uv \
163180
# These are typically static configuration that changes infrequently
164181
COPY config/ ./config/
165182

166-
# 2. Database migration files (change infrequently)
167-
# Alembic migrations are relatively stable
168-
COPY src/tux/database/migrations/ ./src/tux/database/migrations/
183+
# 2. Database schema files (change infrequently)
184+
# Prisma schema and migrations are relatively stable
185+
COPY prisma/ ./prisma/
169186

170187
# 3. Main application code (changes more frequently)
171188
# The core bot code is most likely to change during development
172-
# Copy the entire src tree so Poetry can find packages from "src"
173-
COPY src/ ./src/
174-
# Keep runtime path stable at /app/tux for later stages and health checks
175-
RUN cp -a src/tux ./tux
189+
COPY tux/ ./tux/
176190

177191
# 4. Root level files needed for installation
178192
# These include metadata and licensing information
@@ -201,9 +215,12 @@ RUN set -eux; \
201215
fi; \
202216
echo "Building version: $(cat /app/VERSION)"
203217

204-
# Sync the project
205-
RUN --mount=type=cache,target=/root/.cache/uv \
206-
uv sync --locked
218+
# Install the application and generate Prisma client
219+
# COMPLEXITY: This step requires multiple operations that must be done together
220+
RUN --mount=type=cache,target=$POETRY_CACHE_DIR \
221+
--mount=type=cache,target=/root/.cache \
222+
# Install the application package itself
223+
poetry install --only main
207224

208225
# ==============================================================================
209226
# DEVELOPMENT STAGE - Development Environment
@@ -232,7 +249,7 @@ RUN set -eux; \
232249
chsh -s /usr/bin/zsh && \
233250
apt-get clean && \
234251
rm -rf /var/lib/apt/lists/*; \
235-
fi
252+
fi; \
236253
# Fix ownership of all application files for non-root user
237254
# SECURITY: Ensures the application runs with proper permissions
238255
COPY --from=build --chown=nonroot:nonroot /app /app
@@ -241,21 +258,22 @@ RUN set -eux; \
241258
# Create application cache and temporary directories
242259
# These directories are used by the bot for caching and temporary files
243260
mkdir -p /app/.cache/tldr /app/temp; \
244-
# Create user cache directories (fixes permission issues for npm and other tools)
261+
# Create user cache directories (fixes permission issues for Prisma/npm)
245262
mkdir -p /home/nonroot/.cache /home/nonroot/.npm; \
246-
# Ensure correct ownership for nonroot user to write into these directories
247-
chown -R nonroot:nonroot /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm
248263
# Switch to non-root user for all subsequent operations
249264
# SECURITY: Follows principle of least privilege
250265
USER nonroot
251266

252-
# Install development dependencies
267+
# Install development dependencies and setup Prisma
253268
# DEVELOPMENT: These tools are needed for linting, testing, and development workflow
254-
RUN uv sync --dev
269+
RUN poetry install --only dev --no-root --no-directory && \
270+
poetry run prisma py fetch && \
271+
poetry run prisma generate
255272

256273
# Development container startup command
257-
# WORKFLOW: Starts the bot in development mode with automatic database migrations
258-
CMD ["uv", "run", "tux", "--dev", "start"]
274+
# WORKFLOW: Regenerates Prisma client and starts the bot in development mode
275+
# This ensures the database client is always up-to-date with schema changes
276+
CMD ["sh", "-c", "poetry run prisma generate && exec poetry run tux --dev start"]
259277

260278
# ==============================================================================
261279
# PRODUCTION STAGE - Minimal Runtime Environment
@@ -266,7 +284,7 @@ CMD ["uv", "run", "tux", "--dev", "start"]
266284
# Size Impact: ~440MB (73% reduction from development image)
267285
# ==============================================================================
268286

269-
FROM python:3.13.5-slim@sha256:4c2cf9917bd1cbacc5e9b07320025bdb7cdf2df7b0ceaccb55e9dd7e30987419 AS production
287+
FROM python:3.13.7-slim@sha256:27f90d79cc85e9b7b2560063ef44fa0e9eaae7a7c3f5a9f74563065c5477cc24 AS production
270288

271289
# Duplicate OCI labels for production image metadata
272290
# COMPLIANCE: Ensures production images have proper metadata for registries
@@ -293,17 +311,18 @@ RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
293311
echo 'path-exclude /usr/share/man/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
294312
echo 'path-exclude /usr/share/groff/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
295313
echo 'path-exclude /usr/share/info/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
296-
echo 'path-exclude /usr/share/lintian/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc
314+
echo 'path-exclude /usr/share/lintian/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
315+
echo 'path-exclude /usr/share/linda/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc
297316

298317
# Install ONLY runtime dependencies (minimal subset of base stage)
299318
# SECURITY: Update all packages first, then install minimal runtime dependencies
300319
# SIZE: Significantly smaller than build stage dependencies
301320
RUN apt-get update && \
302321
apt-get upgrade -y && \
303322
apt-get install -y --no-install-recommends --no-install-suggests \
304-
libcairo2=1.16.0-7 \
305-
libffi8=3.4.4-1 \
306-
coreutils=9.1-1 \
323+
libcairo2=1.18.4-1+b1 \
324+
libffi8=3.4.8-2 \
325+
coreutils=9.7-3 \
307326
# Aggressive cleanup to minimize image size
308327
&& apt-get clean \
309328
&& rm -rf /var/lib/apt/lists/* \
@@ -336,7 +355,7 @@ ENV VIRTUAL_ENV=/app/.venv \
336355
# EFFICIENCY: Only copies what's needed for runtime
337356
COPY --from=build --chown=nonroot:nonroot /app/.venv /app/.venv
338357
COPY --from=build --chown=nonroot:nonroot /app/tux /app/tux
339-
358+
COPY --from=build --chown=nonroot:nonroot /app/prisma /app/prisma
340359
COPY --from=build --chown=nonroot:nonroot /app/config /app/config
341360
COPY --from=build --chown=nonroot:nonroot /app/pyproject.toml /app/pyproject.toml
342361
COPY --from=build --chown=nonroot:nonroot /app/VERSION /app/VERSION
@@ -353,32 +372,35 @@ RUN set -eux; \
353372
rm -rf /home/nonroot/.npm/_cacache_; \
354373
chown nonroot:nonroot /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm
355374

356-
# Switch to non-root user for final optimizations
375+
# Switch to non-root user and finalize Prisma binaries
357376
USER nonroot
377+
RUN /app/.venv/bin/python -m prisma py fetch \
378+
&& /app/.venv/bin/python -m prisma generate
358379

359380
USER root
360-
# Aggressive cleanup and optimization
381+
# Aggressive cleanup and optimization after Prisma setup
361382
# PERFORMANCE: Single RUN reduces layer count and enables atomic cleanup
362-
# SIZE: Removes unnecessary files to minimize final image size
383+
# SIZE: Removes unnecessary files to minimize final image size but preserves Prisma binaries
363384
RUN set -eux; \
364385
# VIRTUAL ENVIRONMENT CLEANUP
365386
# The following operations remove unnecessary files from the Python environment
366387
# This can reduce the size by 30-50MB without affecting functionality
367388
# Remove Python bytecode files (will be regenerated as needed)
368389
find /app/.venv -name "*.pyc" -delete; \
369390
find /app/.venv -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true; \
370-
# Remove test directories from installed packages
391+
# Remove test directories from installed packages (but preserve prisma binaries)
371392
# These directories contain test files that are not needed in production
372-
for test_dir in tests testing "*test*"; do \
373-
find /app/.venv -name "$test_dir" -type d -exec rm -rf {} + 2>/dev/null || true; \
393+
for test_dir in tests testing "test*"; do \
394+
find /app/.venv -name "$test_dir" -type d -not -path "*/prisma*" -exec rm -rf {} + 2>/dev/null || true; \
374395
done; \
375-
# Remove documentation files from installed packages
396+
# Remove documentation files from installed packages (but preserve prisma docs)
376397
# These files take up significant space and are not needed in production
377398
for doc_pattern in "*.md" "*.txt" "*.rst" "LICENSE*" "NOTICE*" "COPYING*" "CHANGELOG*" "README*" "HISTORY*" "AUTHORS*" "CONTRIBUTORS*"; do \
378-
find /app/.venv -name "$doc_pattern" -delete 2>/dev/null || true; \
399+
find /app/.venv -name "$doc_pattern" -not -path "*/prisma*" -delete 2>/dev/null || true; \
379400
done; \
380401
# Remove large development packages that are not needed in production
381402
# These packages (pip, setuptools, wheel) are only needed for installing packages
403+
# NOTE: Preserving packages that Prisma might need
382404
for pkg in setuptools wheel pkg_resources; do \
383405
rm -rf /app/.venv/lib/python3.13/site-packages/${pkg}* 2>/dev/null || true; \
384406
rm -rf /app/.venv/bin/${pkg}* 2>/dev/null || true; \
@@ -387,7 +409,7 @@ RUN set -eux; \
387409
# Compile Python bytecode for performance optimization
388410
# PERFORMANCE: Pre-compiled bytecode improves startup time
389411
# Note: Some compilation errors are expected and ignored
390-
/app/.venv/bin/python -m compileall -b -q /app/src/tux /app/.venv/lib/python3.13/site-packages 2>/dev/null || true
412+
/app/.venv/bin/python -m compileall -b -q /app/tux /app/.venv/lib/python3.13/site-packages 2>/dev/null || true
391413

392414
# Switch back to non-root user for runtime
393415
USER nonroot
@@ -396,7 +418,7 @@ USER nonroot
396418
# MONITORING: Allows Docker/Kubernetes to monitor application health
397419
# RELIABILITY: Enables automatic restart of unhealthy containers
398420
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
399-
CMD python -c "import tux.cli.core; import tux.shared.config.env; print('Health check passed')" || exit 1
421+
CMD python -c "import tux.cli.core; import tux.utils.env; print('Health check passed')" || exit 1
400422

401423
# --interval=30s : Check health every 30 seconds
402424
# --timeout=10s : Allow 10 seconds for health check to complete

src/tux/services/handlers/event.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async def handle_harmful_message(message: discord.Message) -> None:
3535
None
3636
"""
3737

38-
if message.author.bot:
38+
if message.author.bot and message.webhook_id not in CONFIG.BRIDGE_WEBHOOK_IDS:
3939
return
4040

4141
stripped_content = strip_formatting(message.content)

0 commit comments

Comments
 (0)