From 4454e9aef5356e304836e7a32678478a6f201c41 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Tue, 4 Nov 2025 12:40:53 -0500 Subject: [PATCH] Adding renovate stuff. Signed-off-by: Cliff Hill --- .gitea/workflows/renovate.yml | 158 +++++++++++++++++++ README.md | 6 + docs/RENOVATE_SETUP_GUIDE.md | 270 ++++++++++++++++++++++++++++++++ renovate.json | 98 +++++++++++- scripts/quick-renovate-check.sh | 109 +++++++++++++ scripts/validate-renovate.sh | 154 ++++++++++++++++++ 6 files changed, 792 insertions(+), 3 deletions(-) create mode 100644 .gitea/workflows/renovate.yml create mode 100644 docs/RENOVATE_SETUP_GUIDE.md create mode 100644 scripts/quick-renovate-check.sh create mode 100755 scripts/validate-renovate.sh diff --git a/.gitea/workflows/renovate.yml b/.gitea/workflows/renovate.yml new file mode 100644 index 0000000..4956460 --- /dev/null +++ b/.gitea/workflows/renovate.yml @@ -0,0 +1,158 @@ +name: Renovate Dependency Updates + +on: + schedule: + # Run Renovate every Monday at 8 AM UTC + - cron: '0 8 * * 1' + workflow_dispatch: # Allow manual triggering + inputs: + dry_run: + description: 'Run in dry-run mode (no changes made)' + required: false + default: 'false' + type: boolean + +jobs: + renovate: + name: Renovate Dependencies + runs-on: ubuntu-act + + steps: + - name: Checkout repository + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + echo "=== Repository Checkout for Renovate ===" + + # Set up SSH key securely + if [ -n "${SSH_PRIVATE_KEY}" ]; then + mkdir -p ~/.ssh + echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -p 2222 dogar.darkhelm.org >> ~/.ssh/known_hosts 2>/dev/null + fi + + # Clone repository + GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" \ + git clone --depth 1 \ + ssh://git@dogar.darkhelm.org:2222/DarkHelm.org/plex-playlist.git . + + # Clean up SSH key + rm -f ~/.ssh/id_rsa + + echo "✓ Repository checked out for Renovate processing" + + - name: Setup Node.js for Renovate + run: | + # Install Node.js 24 (required for Renovate 41+) + curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - + sudo apt-get install -y nodejs + + # Update npm to latest version + npm install -g npm@latest + + # Verify installation + echo "Node.js version: $(node --version)" + echo "npm version: $(npm --version)" + + # Check if versions meet Renovate requirements + NODE_VERSION=$(node --version | cut -d'v' -f2) + if [[ $(echo "$NODE_VERSION 24.10.0" | awk '{print ($1 >= $2)}') == 1 ]]; then + echo "✓ Node.js version $NODE_VERSION meets Renovate requirements" + else + echo "⚠️ Node.js version $NODE_VERSION may not fully support latest Renovate" + fi + + - name: Install Renovate + run: | + echo "Installing compatible Renovate version..." + # Use a specific version that works with Node 24.6+ + npm install -g renovate@40.3.2 + renovate --version + + - name: Configure Renovate for Gitea + env: + RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} + run: | + echo "=== Configuring Renovate for Gitea ===" + + # Create Renovate configuration file + cat > renovate-config.js << 'EOF' + module.exports = { + platform: 'gitea', + endpoint: 'https://dogar.darkhelm.org/api/v1', + token: process.env.RENOVATE_TOKEN, + gitAuthor: 'Renovate Bot ', + repositories: ['DarkHelm.org/plex-playlist'], + onboarding: false, + requireConfig: 'required', + + // Use existing renovate.json configuration + extends: ['local>DarkHelm.org/plex-playlist'], + + // CI-specific settings + prConcurrentLimit: 3, + branchConcurrentLimit: 5, + + // Logging + logLevel: 'info', + logFile: '/tmp/renovate.log', + + // Dry run mode for testing + dryRun: process.env.RENOVATE_DRY_RUN === 'true' + }; + EOF + + echo "✓ Renovate configuration created" + + - name: Run Renovate + env: + RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} + RENOVATE_DRY_RUN: ${{ inputs.dry_run }} + LOG_LEVEL: info + run: | + echo "=== Running Renovate Bot ===" + + # Verify token is available + if [ -z "${RENOVATE_TOKEN}" ]; then + echo "❌ RENOVATE_TOKEN secret not configured" + echo "Please add a Gitea API token to repository secrets" + exit 1 + fi + + # Run Renovate with configuration + if [ "${RENOVATE_DRY_RUN}" = "true" ]; then + echo "🔍 Running in DRY-RUN mode (no changes will be made)" + fi + + renovate --config-file=renovate-config.js DarkHelm.org/plex-playlist + + echo "✓ Renovate execution completed" + + - name: Upload Renovate logs + if: always() + run: | + if [ -f "/tmp/renovate.log" ]; then + echo "=== Renovate Log Output ===" + echo "Last 50 lines of Renovate log:" + tail -50 /tmp/renovate.log + + # Save log as artifact (if GitHub Actions artifact support exists) + mkdir -p /tmp/artifacts + cp /tmp/renovate.log /tmp/artifacts/renovate-$(date +%Y%m%d-%H%M%S).log + else + echo "No Renovate log file found" + fi + + - name: Report Results + if: always() + run: | + echo "=== Renovate Execution Summary ===" + echo "Repository: DarkHelm.org/plex-playlist" + echo "Execution time: $(date)" + echo "Dry run mode: ${RENOVATE_DRY_RUN:-false}" + echo "" + echo "Check the Dependency Dashboard issue in your repository for detailed results:" + echo "https://dogar.darkhelm.org/DarkHelm.org/plex-playlist/issues" + echo "" + echo "Next scheduled run: Next Monday at 8 AM UTC" diff --git a/README.md b/README.md index 17259b6..4f8b6b2 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,12 @@ npm run dev - **[CI/CD Multi-stage Build](docs/CICD_MULTI_STAGE_BUILD.md)** - Docker multi-stage build strategy, architecture decisions, and performance optimizations - **[CI/CD Troubleshooting Guide](docs/CICD_TROUBLESHOOTING_GUIDE.md)** - Comprehensive troubleshooting, optimization decisions, and performance monitoring for Docker builds and E2E testing +- **[CI/CD Success Summary](docs/CICD_SUCCESS_SUMMARY.md)** - Complete validation results and performance metrics for the optimized pipeline + +### Dependency Management & Automation + +- **[Renovate Bot Setup](docs/RENOVATE_SETUP_GUIDE.md)** - Automated dependency updates with Renovate for Python, Node.js, and Docker dependencies +- **[Gitea API Token Setup](docs/GITEA_TOKEN_SETUP.md)** - Step-by-step guide for creating organization API tokens with proper permissions ### Operations & Troubleshooting diff --git a/docs/RENOVATE_SETUP_GUIDE.md b/docs/RENOVATE_SETUP_GUIDE.md new file mode 100644 index 0000000..a900c03 --- /dev/null +++ b/docs/RENOVATE_SETUP_GUIDE.md @@ -0,0 +1,270 @@ +# Renovate Bot Setup Guide + +## Overview + +Renovate is an automated dependency update tool that creates pull requests to keep your project dependencies up to date. This guide covers setting up Renovate for the plex-playlist project with optimal configuration. + +## Setup Options + +### Option 1: GitHub App (Recommended for GitHub) + +1. **Install Renovate App**: + - Go to [Renovate GitHub App](https://github.com/apps/renovate) + - Click "Install" and select your repository + - Choose repository access (single repo or organization-wide) + +2. **Configure Repository Access**: + - Select the `plex-playlist` repository + - Grant necessary permissions (read/write to repository, pull requests, issues) + +3. **Initial Configuration**: + - Renovate will automatically detect the `renovate.json` file + - Creates an onboarding PR to explain the configuration + - Review and merge the onboarding PR to activate + +### Option 2: Self-Hosted (For Gitea/Custom Git Servers) + +Since your project uses `dogar.darkhelm.org` (Gitea), you'll need to run Renovate as a service: + +#### Docker-based Self-Hosted Setup + +1. **Create Renovate Configuration**: + +```bash +# Create renovate directory +mkdir -p ~/.config/renovate +``` + +2. **Create Renovate Bot Token**: + - **For Organization Repositories**: See detailed guide → **[Gitea Token Setup](GITEA_TOKEN_SETUP.md)** + - Required scopes: `repo`, `write:repo_hook`, `read:org`, `write:issue`, `write:pull_request` + - Save token securely for next step + +3. **Create Environment Configuration**: + +```bash +# ~/.config/renovate/config.js +module.exports = { + platform: 'gitea', + endpoint: 'https://dogar.darkhelm.org/api/v1', + token: process.env.RENOVATE_TOKEN, + gitAuthor: 'Renovate Bot ', + repositories: ['DarkHelm.org/plex-playlist'], + onboarding: false, // Skip onboarding PR + requireConfig: 'required' // Use existing renovate.json +}; +``` + +4. **Run with Docker**: + +```bash +# Run Renovate Bot +docker run --rm \ + -e RENOVATE_TOKEN="your_gitea_token_here" \ + -v ~/.config/renovate/config.js:/usr/src/app/config.js \ + renovate/renovate:latest +``` + +#### Scheduled Automation + +Create a systemd timer or cron job to run Renovate periodically: + +```bash +# /etc/cron.d/renovate-bot +# Run Renovate every Monday at 8 AM +0 8 * * 1 root docker run --rm -e RENOVATE_TOKEN="$RENOVATE_TOKEN" -v ~/.config/renovate/config.js:/usr/src/app/config.js renovate/renovate:latest +``` + +### Option 3: CI/CD Integration + +Add Renovate to your existing Gitea Actions workflow: + +```yaml +# .gitea/workflows/renovate.yml +name: Renovate +on: + schedule: + - cron: '0 8 * * 1' # Monday 8 AM + workflow_dispatch: # Manual trigger + +jobs: + renovate: + runs-on: ubuntu-act + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run Renovate + uses: renovatebot/github-action@v40.3.2 + with: + configurationFile: renovate.json + token: ${{ secrets.RENOVATE_TOKEN }} + env: + RENOVATE_PLATFORM: gitea + RENOVATE_ENDPOINT: https://dogar.darkhelm.org/api/v1 +``` + +## Configuration Explanation + +### Key Features of Our Configuration + +1. **Smart Scheduling**: + - Regular updates: Weekday mornings before 9 AM + - Security updates: Any time + - Grouped updates: Monday mornings + +2. **Automerge Strategy**: + - **Auto**: Minor/patch updates for trusted packages (types, linting tools) + - **Manual**: Major updates, Docker base images, security fixes + +3. **Grouping**: + - **Python dev tools**: ruff, pytest, mypy, etc. + - **Frontend dev tools**: eslint, prettier, typescript, etc. + - **Docker base images**: ubuntu, python, node versions + +4. **Custom Managers**: + - Detects Python/Node versions in Dockerfiles + - Updates base image versions automatically + +### Package Manager Support + +Our configuration handles: + +- **Python (uv)**: `backend/pyproject.toml` +- **Node.js (Yarn)**: `frontend/package.json` + `frontend/yarn.lock` +- **Docker**: All `Dockerfile.*` files +- **GitHub Actions**: `.gitea/workflows/*.yml` (if using actions) + +## Testing the Configuration + +### 1. Validate Configuration + +```bash +# Install Renovate CLI for testing +npm install -g renovate + +# Validate configuration +renovate-config-validator renovate.json + +# Dry run (shows what would be updated) +renovate --dry-run --log-level=debug DarkHelm.org/plex-playlist +``` + +### 2. Expected Behavior + +Once active, Renovate will: + +1. **Scan Dependencies**: Daily check for updates +2. **Create PRs**: Individual PRs for each update group +3. **Auto-merge**: Safe updates (minor/patch) merge automatically +4. **Security Alerts**: Immediate PRs for vulnerability fixes +5. **Dependency Dashboard**: Issue with update status overview + +### 3. Integration with CI/CD + +Renovate PRs will trigger your existing CI/CD pipeline: +- Build and test in Docker containers +- Run full quality gates (linting, type checking, tests) +- Only merge if all checks pass + +## Monitoring and Maintenance + +### Dashboard + +Renovate creates a "Dependency Dashboard" issue showing: +- Pending updates +- Failed PRs +- Ignored dependencies +- Configuration errors + +### Logs and Debugging + +For self-hosted setup: +```bash +# Run with debug logging +docker run --rm \ + -e LOG_LEVEL=debug \ + -e RENOVATE_TOKEN="your_token" \ + -v ~/.config/renovate/config.js:/usr/src/app/config.js \ + renovate/renovate:latest +``` + +### Common Issues + +1. **Node.js Version Compatibility**: + - Renovate 41+ requires Node.js 24.10.0+ or 22.13.0+ + - Use `renovate@40.3.2` for older Node.js versions + - Our CI workflow automatically handles this + +2. **Token Permissions**: Ensure Gitea token has repo write access +3. **Rate Limiting**: Adjust `prHourlyLimit` if hitting API limits +4. **Large Updates**: Major version updates may need manual review +5. **Docker Registry**: Ensure base image updates don't break builds + +### Quick Validation + +For basic JSON validation without installing Renovate: +```bash +# Quick syntax check (no Renovate installation needed) +./scripts/quick-renovate-check.sh + +# Full validation (requires Renovate installation) +./scripts/validate-renovate.sh +``` + +## Security Considerations + +1. **Token Security**: Store Renovate token in secrets management +2. **Branch Protection**: Ensure main branch requires PR reviews +3. **Automerge Limits**: Only automerge trusted, low-risk updates +4. **Vulnerability Alerts**: Enable immediate security update PRs + +## Advanced Configuration + +### Custom Rules Example + +```json +{ + "packageRules": [ + { + "description": "Pin exact versions for critical packages", + "matchPackageNames": ["fastapi", "@types/node"], + "rangeStrategy": "pin" + }, + { + "description": "Ignore beta/alpha releases", + "matchPackagePatterns": [".*"], + "ignoreUnstable": true + } + ] +} +``` + +### Notification Integration + +```json +{ + "notifications": [ + { + "platform": "slack", + "endpoint": "https://hooks.slack.com/services/...", + "channels": ["#dev-notifications"] + } + ] +} +``` + +## Next Steps + +1. **Choose Setup Method**: GitHub App (if on GitHub) or self-hosted (for Gitea) +2. **Generate API Token**: Create token with appropriate permissions +3. **Test Configuration**: Run dry-run to verify setup +4. **Monitor First Updates**: Review initial PRs to ensure proper operation +5. **Adjust Settings**: Fine-tune automerge rules based on project needs + +--- + +**Related Documentation**: +- [Renovate Official Docs](https://docs.renovatebot.com/) +- [Configuration Options](https://docs.renovatebot.com/configuration-options/) +- [Package Rules](https://docs.renovatebot.com/configuration-options/#packagerules) diff --git a/renovate.json b/renovate.json index aa2f144..a564e38 100644 --- a/renovate.json +++ b/renovate.json @@ -1,10 +1,102 @@ { - "extends": ["config:recommended"], + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":dependencyDashboard", + ":semanticCommits", + ":separatePatchReleases" + ], + "timezone": "America/New_York", + "schedule": ["before 9am every weekday"], + "prConcurrentLimit": 5, + "branchConcurrentLimit": 10, + "prHourlyLimit": 2, + "packageRules": [ { + "description": "Automerge non-major updates for high-confidence packages", "matchUpdateTypes": ["minor", "patch", "pin", "digest"], - "automerge": true + "matchPackagePatterns": ["^@types/", "^eslint", "^prettier", "^ruff", "^pytest"], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Group Python dev tools updates", + "matchManagers": ["uv"], + "matchCategories": ["python"], + "matchDepTypes": ["dev-dependencies"], + "groupName": "Python dev tools", + "schedule": ["before 9am on monday"] + }, + { + "description": "Group Frontend dev tools updates", + "matchManagers": ["npm"], + "matchDepTypes": ["devDependencies"], + "matchPackagePatterns": ["^@typescript-eslint/", "^eslint", "^prettier", "^vite", "^vitest", "^playwright"], + "groupName": "Frontend dev tools", + "schedule": ["before 9am on monday"] + }, + { + "description": "Group Docker base image updates", + "matchManagers": ["dockerfile"], + "matchPackageNames": ["ubuntu", "node", "python"], + "groupName": "Docker base images", + "schedule": ["before 9am on monday"], + "automerge": false, + "reviewersFromCodeOwners": true + }, + { + "description": "Security updates - high priority", + "matchPackagePatterns": [".*"], + "vulnerabilityAlerts": true, + "prPriority": 10, + "automerge": false, + "labels": ["security"], + "reviewersFromCodeOwners": true + }, + { + "description": "Major updates - require manual review", + "matchUpdateTypes": ["major"], + "automerge": false, + "labels": ["major-update"], + "prPriority": 5, + "reviewersFromCodeOwners": true } ], - "osvVulnerabilityAlerts": true + + "customManagers": [ + { + "description": "Update Python version in Dockerfiles", + "customType": "regex", + "fileMatch": ["^Dockerfile.*$"], + "matchStrings": ["FROM python:(?\\d+\\.\\d+)"], + "datasourceTemplate": "docker", + "depNameTemplate": "python", + "versioningTemplate": "loose" + }, + { + "description": "Update Node.js version in Dockerfiles", + "customType": "regex", + "fileMatch": ["^Dockerfile.*$"], + "matchStrings": ["FROM node:(?\\d+)"], + "datasourceTemplate": "docker", + "depNameTemplate": "node", + "versioningTemplate": "node" + } + ], + + "osvVulnerabilityAlerts": true, + "vulnerabilityAlerts": { + "enabled": true, + "schedule": ["at any time"] + }, + + "labels": ["dependencies"], + "commitMessagePrefix": "chore:", + "commitMessageTopic": "{{depName}}", + "commitMessageExtra": "to {{newVersion}}", + "commitMessageSuffix": "", + + "prTitle": "{{commitMessagePrefix}} {{commitMessageAction}} {{commitMessageTopic}} {{commitMessageExtra}}", + "prBodyTemplate": "This PR contains the following updates:\n\n| Package | Change | Age | Adoption | Passing | Confidence |\n|---|---|---|---|---|---|\n{{#each upgrades}}\n|{{depName}}|{{#if displayFrom}}`{{{displayFrom}}}` -> `{{{displayTo}}}`{{else}}`{{{newVersion}}}`{{/if}}|[![age](https://badges.renovateapi.com/packages/{{datasource}}/{{depName}}/{{newVersion}}/age-slim)](https://docs.renovatebot.com/merge-confidence/)|[![adoption](https://badges.renovateapi.com/packages/{{datasource}}/{{depName}}/{{newVersion}}/adoption-slim)](https://docs.renovatebot.com/merge-confidence/)|[![passing](https://badges.renovateapi.com/packages/{{datasource}}/{{depName}}/{{newVersion}}/compatibility-slim/{{currentVersion}})](https://docs.renovatebot.com/merge-confidence/)|[![confidence](https://badges.renovateapi.com/packages/{{datasource}}/{{depName}}/{{newVersion}}/confidence-slim/{{currentVersion}})](https://docs.renovatebot.com/merge-confidence/)|\n{{/each}}\n\n---\n\n### Release Notes\n\n{{#each upgrades}}\n{{#if hasReleaseNotes}}\n
\n{{depName}}\n\n{{#each releases}}\n#### {{title}}\n\n{{#if body}}\n{{body}}\n{{/if}}\n{{/each}}\n\n
\n{{/if}}\n{{/each}}\n\n### Configuration\n\n📅 **Schedule**: {{schedule}}\n\n🚦 **Automerge**: {{#if isAutomerge}}Enabled{{else}}Disabled{{/if}}\n\n♻ **Rebasing**: {{#if isRebasing}}Rebasing{{else}}Not rebasing{{/if}}\n\n👥 **Reviewers**: {{#if reviewers}}{{reviewers}}{{else}}None{{/if}}\n\n---\n\n*This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).*" } diff --git a/scripts/quick-renovate-check.sh b/scripts/quick-renovate-check.sh new file mode 100644 index 0000000..826863c --- /dev/null +++ b/scripts/quick-renovate-check.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# Quick Renovate JSON Validator +# Simple validation that doesn't require Renovate installation + +echo "🔍 Quick Renovate Configuration Check" +echo "=====================================" + +# Check if renovate.json exists +if [ ! -f "renovate.json" ]; then + echo "❌ renovate.json not found in current directory" + exit 1 +fi + +echo "✓ Found renovate.json" + +# Validate JSON syntax with Node.js (should be available) +if command -v node &> /dev/null; then + echo "" + echo "🔧 Validating JSON syntax..." + + if node -e " + try { + const config = JSON.parse(require('fs').readFileSync('renovate.json', 'utf8')); + console.log('✓ JSON syntax is valid'); + console.log('✓ Configuration has', Object.keys(config).length, 'top-level properties'); + + // Check for required/recommended fields + if (config.extends) { + console.log('✓ Base configuration extends:', config.extends); + } + if (config.schedule) { + console.log('✓ Update schedule configured'); + } + if (config.packageRules) { + console.log('✓ Package rules defined:', config.packageRules.length, 'rules'); + } + + } catch(e) { + console.error('❌ JSON syntax error:', e.message); + process.exit(1); + }"; then + echo "✓ JSON validation passed" + else + echo "❌ JSON validation failed" + exit 1 + fi +else + echo "⚠️ Node.js not available, skipping JSON validation" +fi + +# Check for supported package files +echo "" +echo "📋 Checking for supported package managers..." + +PACKAGE_FILES_FOUND=0 + +# Python (uv/pip) +if [ -f "backend/pyproject.toml" ]; then + echo "✓ Python: backend/pyproject.toml" + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) +fi + +# Node.js (npm/yarn) +if [ -f "frontend/package.json" ]; then + echo "✓ Node.js: frontend/package.json" + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) + + # Check for yarn.lock + if [ -f "frontend/yarn.lock" ]; then + echo " └─ Yarn PnP detected (yarn.lock present)" + fi +fi + +# Docker +DOCKERFILE_COUNT=$(find . -name "Dockerfile*" -type f | wc -l) +if [ $DOCKERFILE_COUNT -gt 0 ]; then + echo "✓ Docker: $DOCKERFILE_COUNT Dockerfile(s) found" + find . -name "Dockerfile*" -type f | head -3 | sed 's|^./| └─ |' + if [ $DOCKERFILE_COUNT -gt 3 ]; then + echo " └─ ... and $((DOCKERFILE_COUNT - 3)) more" + fi + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) +fi + +# GitHub Actions / Gitea Actions +WORKFLOW_COUNT=$(find .gitea/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | wc -l) +if [ $WORKFLOW_COUNT -gt 0 ]; then + echo "✓ Gitea Actions: $WORKFLOW_COUNT workflow(s) found" +fi + +if [ $PACKAGE_FILES_FOUND -eq 0 ]; then + echo "⚠️ No supported package files found" + echo " Renovate looks for: pyproject.toml, package.json, Dockerfile, etc." +else + echo "✓ Found $PACKAGE_FILES_FOUND package manager types to monitor" +fi + +echo "" +echo "🚀 Status: Basic configuration validation complete!" +echo "" +echo "📋 Next steps:" +echo " 1. Add RENOVATE_TOKEN secret to your Gitea repository" +echo " 2. Enable .gitea/workflows/renovate.yml workflow" +echo " 3. Test with manual workflow trigger (dry-run mode)" +echo "" +echo "📚 For full validation, see: docs/RENOVATE_SETUP_GUIDE.md" +echo "" +echo "✅ Quick validation complete!" diff --git a/scripts/validate-renovate.sh b/scripts/validate-renovate.sh new file mode 100755 index 0000000..823e7d3 --- /dev/null +++ b/scripts/validate-renovate.sh @@ -0,0 +1,154 @@ +#!/bin/bash + +# Renovate Configuration Validator +# This script validates the renovate.json configuration and checks for common issues + +set -e + +echo "🔍 Renovate Configuration Validator" +echo "==================================" + +# Check if renovate.json exists +if [ ! -f "renovate.json" ]; then + echo "❌ renovate.json not found in current directory" + exit 1 +fi + +echo "✓ Found renovate.json" + +# Check if Node.js is available +if ! command -v node &> /dev/null; then + echo "⚠️ Node.js not found, installing..." + # For Ubuntu/Debian systems + if command -v apt-get &> /dev/null; then + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs + else + echo "❌ Please install Node.js 18+ to validate configuration" + exit 1 + fi +fi + +# Install renovate CLI if not present +if ! command -v renovate &> /dev/null; then + echo "📦 Installing Renovate CLI..." + # Check Node.js version and install compatible Renovate version + NODE_VERSION=$(node --version | cut -d'v' -f2) + if [[ $(echo "$NODE_VERSION 24.10.0" | awk '{print ($1 >= $2)}') == 1 ]]; then + echo "Installing latest Renovate for Node.js $NODE_VERSION" + npm install -g renovate@latest + else + echo "Installing compatible Renovate version for Node.js $NODE_VERSION" + npm install -g renovate@40.3.2 + fi +fi + +echo "✓ Renovate CLI available" + +# Validate configuration syntax +echo "" +echo "🔧 Validating renovate.json syntax..." + +# First, validate JSON syntax +if ! node -e " +try { + const config = JSON.parse(require('fs').readFileSync('renovate.json', 'utf8')); + console.log('✓ JSON syntax is valid'); + console.log('✓ Configuration has', Object.keys(config).length, 'top-level properties'); +} catch(e) { + console.error('❌ JSON syntax error:', e.message); + process.exit(1); +}"; then + exit 1 +fi + +# Then, test Renovate can parse the config (basic validation) +echo "🔍 Testing Renovate configuration parsing..." +if timeout 30 renovate --dry-run --log-level=warn . 2>&1 | grep -qi "error\|fatal"; then + echo "⚠️ Renovate reported warnings/errors during config parsing" + echo "ℹ️ Run 'renovate --dry-run --log-level=debug .' for detailed analysis" + echo "ℹ️ This may be normal for first-time setup" +else + echo "✓ Renovate configuration parsing completed" +fi + +# Check for required package files +echo "" +echo "📋 Checking for supported package managers..." + +PACKAGE_FILES_FOUND=0 + +# Python (uv/pip) +if [ -f "backend/pyproject.toml" ]; then + echo "✓ Python: backend/pyproject.toml" + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) +fi + +# Node.js (npm/yarn) +if [ -f "frontend/package.json" ]; then + echo "✓ Node.js: frontend/package.json" + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) +fi + +# Docker +DOCKERFILE_COUNT=$(find . -name "Dockerfile*" -type f | wc -l) +if [ $DOCKERFILE_COUNT -gt 0 ]; then + echo "✓ Docker: $DOCKERFILE_COUNT Dockerfile(s) found" + PACKAGE_FILES_FOUND=$((PACKAGE_FILES_FOUND + 1)) +fi + +# GitHub Actions (if any) +WORKFLOW_COUNT=$(find .gitea/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | wc -l) +if [ $WORKFLOW_COUNT -gt 0 ]; then + echo "✓ Gitea Actions: $WORKFLOW_COUNT workflow(s) found" +fi + +if [ $PACKAGE_FILES_FOUND -eq 0 ]; then + echo "⚠️ No supported package files found" + echo " Renovate looks for: pyproject.toml, package.json, Dockerfile, etc." +else + echo "✓ Found $PACKAGE_FILES_FOUND package manager types" +fi + +# Validate common configuration issues +echo "" +echo "🔍 Checking configuration best practices..." + +# Check for timezone setting +if grep -q "timezone" renovate.json; then + echo "✓ Timezone configured" +else + echo "ℹ️ Consider adding timezone setting for consistent scheduling" +fi + +# Check for schedule configuration +if grep -q "schedule" renovate.json; then + echo "✓ Update schedule configured" +else + echo "ℹ️ Consider adding schedule to control when updates run" +fi + +# Check for automerge rules +if grep -q "automerge" renovate.json; then + echo "✓ Automerge rules configured" +else + echo "ℹ️ Consider configuring automerge for safe updates" +fi + +# Check for vulnerability alerts +if grep -q "vulnerabilityAlerts\|osvVulnerabilityAlerts" renovate.json; then + echo "✓ Security vulnerability alerts enabled" +else + echo "⚠️ Consider enabling vulnerability alerts for security updates" +fi + +echo "" +echo "🚀 Next Steps for Gitea Setup:" +echo "1. Create a Gitea API token with repository access" +echo "2. Add the token as RENOVATE_TOKEN in repository secrets" +echo "3. Enable the renovate.yml workflow in Gitea Actions" +echo "4. Test with manual workflow trigger (dry-run mode)" +echo "" +echo "📚 Documentation: docs/RENOVATE_SETUP_GUIDE.md" +echo "" +echo "✅ Configuration validation complete!"