Skip to content
Open
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
86 changes: 85 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,87 @@
# Dependencies
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Git
.git
.env
.gitignore
.gitattributes

# Documentation
README.md
CHANGELOG.md
TODO.md
*.md

# IDE and Editor files
.vscode
.idea
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Docker files
Dockerfile*
docker-compose*.yml
.dockerignore
Comment on lines +42 to +44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Don't ignore Dockerfile(s) and compose files.

Excluding these can break docker builds and tooling that rely on default locations.

Proposed change:

-# Docker files
-Dockerfile*
-docker-compose*.yml
 .dockerignore

Verify your build script doesn’t depend on these being in context:


🏁 Script executed:

#!/bin/bash
# Search docker build invocations; ensure -f is used if Dockerfile is ignored
rg -nP 'docker\s+build' -C2
rg -nP 'docker-compose|docker compose' -C2

Length of output: 3215


Remove Dockerfile* and docker-compose*.yml from .dockerignore
These files are required by default docker build (no -f) and docker-compose up commands.

-Dockerfile*
-docker-compose*.yml
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Dockerfile*
docker-compose*.yml
.dockerignore
.dockerignore
🤖 Prompt for AI Agents
In .dockerignore around lines 42 to 44, the entries "Dockerfile*" and
"docker-compose*.yml" are ignoring files that Docker and docker-compose expect
by default; remove those two patterns from .dockerignore so the default
Dockerfile and any docker-compose yml files are not excluded, leaving other
ignore entries (like .dockerignore) intact.


# CI/CD files
.github
.husky

# Test files
test
tests
*.test.js
*.spec.js

# Coverage
coverage
.nyc_output

# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# Development files
example.*
oldIndex.js
35 changes: 35 additions & 0 deletions .env.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Docker Environment Configuration
# Copy this file to .env and fill in your actual values

# Required Discord Configuration
DISCORD_TOKEN=your_discord_bot_token_here
CLIENT_ID=your_discord_application_client_id

# Required GitHub Configuration
REPO_ORG=streamyfin
REPO_NAME=streamyfin

# Optional GitHub Configuration
GITHUB_TOKEN=your_github_personal_access_token
GITHUB_API_BASE=https://api.github.com

# Optional Discord Channel Configuration
FORUM_CHANNEL_ID=your_forum_channel_id
AI_SUPPORTCHANNEL_ID=your_ai_support_channel_id
MOD_LOG_CHANNEL_ID=your_moderation_log_channel_id
CHANNELS_TO_IGNORE=["channel_id_1","channel_id_2"]

# Optional AI Support Configuration
AI_APIKEY=your_ai_api_key
AI_SUPPORT_URL=your_ai_support_service_url

# Optional Content Moderation
PERSPECTIVE_APIKEY=your_google_perspective_api_key

# Application Configuration
LOG_LEVEL=INFO
ENABLE_RSS_MONITORING=true
NODE_ENV=production

# Redis Configuration (handled by docker-compose)
REDIS_URL=redis://redis:6379
25 changes: 25 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"env": {
"es2022": true,
"node": true
},
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"],
"no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
"no-console": "off",
"prefer-const": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-template": "error"
}
}
99 changes: 99 additions & 0 deletions .github/workflows/dev-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Dev Build & Deploy

on:
push:
branches:
- codebase-rework
workflow_dispatch: # Allow manual triggering

permissions:
contents: read

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

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history to ensure we have all commits

- name: Check for relevant code changes
id: changes
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "RELEVANT_CHANGES=true" >> "${GITHUB_ENV}"
echo "Manual trigger - building dev image"
else
git fetch origin codebase-rework || git fetch origin main
CHANGED=""
# Check if we can access the before commit
if [ -n "${{ github.event.before }}" ] && git cat-file -e "${{ github.event.before }}" 2>/dev/null; then
CHANGED=$(git diff --name-only "${{ github.event.before }}" "${{ github.sha }}" || echo "")
echo "Using commit range: ${{ github.event.before }}..${{ github.sha }}"
else
# Fallback: check if HEAD~1 exists, then diff or show HEAD changes
if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
CHANGED=$(git diff --name-only HEAD~1 HEAD || echo "")
echo "Using fallback: comparing HEAD~1..HEAD"
else
CHANGED=$(git show --name-only --format= HEAD || echo "")
echo "Using fallback: showing HEAD changes (no previous commit)"
fi
fi
echo "Changed files:"
printf '%s\n' "$CHANGED"
if [ -n "$CHANGED" ] && printf '%s' "$CHANGED" | grep -qE '^(commands/|src/|lib/|bot/|index\.js|client\.js|package\.json|Dockerfile|\.github/workflows/)'; then
echo "RELEVANT_CHANGES=true" >> "${GITHUB_ENV}"
echo "✅ Relevant code changes detected"
else
echo "RELEVANT_CHANGES=false" >> "${GITHUB_ENV}"
echo "⚠️ No relevant code changes detected"
fi
fi
- name: Skip workflow if no relevant code changed
if: env.RELEVANT_CHANGES == 'false'
run: echo "⚠️ No relevant code changes – skipping dev build."

- name: Set up Docker Buildx
if: env.RELEVANT_CHANGES == 'true'
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
if: env.RELEVANT_CHANGES == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Extract and sanitize branch name
if: env.RELEVANT_CHANGES == 'true'
shell: bash
run: |
BRANCH_RAW="${{ github.ref_name }}"
# Docker tag charset: [A-Za-z0-9_.-], lower-case recommended; no slashes
BRANCH_SLUG="$(echo "$BRANCH_RAW" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9._-]+/-/g' | sed -E 's/^-+|-+$//g' | cut -c1-120)"
if [ -z "$BRANCH_SLUG" ]; then BRANCH_SLUG="unknown"; fi
echo "BRANCH_SLUG=$BRANCH_SLUG" >> $GITHUB_ENV
echo "Building for branch: $BRANCH_RAW (tag slug: $BRANCH_SLUG)"
- name: Build and push Dev Docker image
if: env.RELEVANT_CHANGES == 'true'
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
retardgerman/streamyfin-discord-bot:dev
retardgerman/streamyfin-discord-bot:dev-${{ env.BRANCH_NAME }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Verify Docker image
if: env.RELEVANT_CHANGES == 'true'
run: |
echo "✅ Dev Docker images built and pushed:"
echo "📦 retardgerman/streamyfin-discord-bot:dev"
echo "📦 retardgerman/streamyfin-discord-bot:dev-${{ env.BRANCH_NAME }}"
52 changes: 49 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@

FROM node:23-alpine
# Multi-stage build for optimized production image
FROM node:22-alpine AS base

# Install dependencies for native modules
RUN apk add --no-cache python3 make g++ libc6-compat

WORKDIR /app


# Copy package files
COPY package*.json ./

FROM base AS dependencies

# Install all dependencies (including dev dependencies)
RUN npm ci --include=dev

RUN npm ci --omit=dev
FROM base AS build

# Copy node_modules from dependencies stage
COPY --from=dependencies /app/node_modules ./node_modules

# Copy source code
COPY . .

# Run linting and validation (optional - can be disabled for faster builds)
RUN npm run lint || echo "Linting failed but continuing build"

FROM node:22-alpine AS production
WORKDIR /app

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Copy application files first
COPY --from=build --chown=nodejs:nodejs /app .

# Ensure production-only dependencies
RUN rm -rf node_modules \
&& npm ci --omit=dev \
&& npm cache clean --force

# Create data directory for logs and cache
RUN mkdir -p /app/data && chown nodejs:nodejs /app/data

# Switch to non-root user
USER nodejs

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD node health-check.js

# Environment variables
ENV NODE_ENV=production \
LOG_LEVEL=INFO \
REDIS_URL=redis://redis:6379

# Expose port (for potential future web interface)
EXPOSE 3000

# Start the application
CMD ["node", "index.js"]
Loading