diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 00000000..b1e933ca --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,71 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":semanticCommits", + ":separateMultipleMajorReleases", + "helpers:pinGitHubActionDigests" + ], + "baseBranches": ["development"], + "timezone": "UTC", + "dependencyDashboard": true, + "prConcurrentLimit": 10, + "prHourlyLimit": 5, + "labels": ["dependencies"], + "rebaseWhen": "conflicted", + "vulnerabilityAlerts": { "enabled": true }, + "schedule": ["every weekday"], + "rangeStrategy": "bump", + "packageRules": [ + { + "description": "Automerge safe patch updates", + "matchUpdateTypes": ["patch"], + "automerge": true + }, + { + "description": "Frontend npm: automerge minor for devDependencies", + "matchManagers": ["npm"], + "matchDepTypes": ["devDependencies"], + "matchUpdateTypes": ["minor", "patch"], + "automerge": true, + "labels": ["dependencies", "npm"] + }, + { + "description": "Backend Go modules", + "matchManagers": ["gomod"], + "labels": ["dependencies", "go"], + "matchUpdateTypes": ["minor", "patch"], + "automerge": false + }, + { + "description": "GitHub Actions updates", + "matchManagers": ["github-actions"], + "labels": ["dependencies", "github-actions"], + "matchUpdateTypes": ["minor", "patch"], + "automerge": true + }, + { + "description": "Docker: keep Caddy within v2 (no automatic jump to v3)", + "matchManagers": ["dockerfile"], + "matchPackageNames": ["caddy"], + "allowedVersions": "<3.0.0", + "labels": ["dependencies", "docker"], + "matchUpdateTypes": ["minor", "patch"], + "automerge": true + }, + { + "description": "Group non-breaking npm minor/patch", + "matchManagers": ["npm"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "npm minor/patch", + "prPriority": -1 + }, + { + "description": "Group docker base minor/patch", + "matchManagers": ["dockerfile"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "docker base updates", + "prPriority": -1 + } + ] +} diff --git a/.github/workflows/caddy-major-monitor.yml b/.github/workflows/caddy-major-monitor.yml new file mode 100644 index 00000000..95635ee3 --- /dev/null +++ b/.github/workflows/caddy-major-monitor.yml @@ -0,0 +1,62 @@ +name: Monitor Caddy Major Release + +on: + schedule: + - cron: '17 7 * * 1' # Mondays at 07:17 UTC + workflow_dispatch: {} + +permissions: + contents: read + issues: write + +jobs: + check-caddy-major: + runs-on: ubuntu-latest + steps: + - name: Check for Caddy v3 and open issue + uses: actions/github-script@v7 + with: + script: | + const upstream = { owner: 'caddyserver', repo: 'caddy' }; + const { data: releases } = await github.rest.repos.listReleases({ + ...upstream, + per_page: 50, + }); + const latestV3 = releases.find(r => /^v3\./.test(r.tag_name)); + if (!latestV3) { + core.info('No Caddy v3 release detected.'); + return; + } + + const issueTitle = `Track upgrade to Caddy v3 (${latestV3.tag_name})`; + + const { data: existing } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page: 100, + }); + + if (existing.some(i => i.title === issueTitle)) { + core.info('Issue already exists — nothing to do.'); + return; + } + + const body = [ + 'Caddy v3 has been released upstream and detected by the scheduled monitor.', + '', + `Detected release: ${latestV3.tag_name} (${latestV3.html_url})`, + '', + '- Create a feature branch to evaluate the v3 migration.', + '- Review breaking changes and update Docker base images/workflows.', + '- Validate Trivy scans and update any policies as needed.', + '', + 'Current policy: remain on latest 2.x until v3 is validated.' + ].join('\n'); + + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: issueTitle, + body, + }); diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 00000000..d28272fa --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,23 @@ +name: Renovate + +on: + schedule: + - cron: '0 5 * * *' # daily 05:00 EST + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - name: Run Renovate + uses: renovatebot/github-action@v40.1.11 + with: + configurationFile: .github/renovate.json + token: ${{ secrets.GITHUB_TOKEN }} + env: + LOG_LEVEL: info diff --git a/Dockerfile b/Dockerfile index 1f80eddb..05fad2a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,9 @@ ARG VERSION=dev ARG BUILD_DATE ARG VCS_REF +# Allow pinning Caddy base image by digest via build-arg +ARG CADDY_IMAGE=caddy:2-alpine + # ---- Frontend Builder ---- # Build the frontend using the BUILDPLATFORM to avoid arm64 musl Rollup native issues FROM --platform=$BUILDPLATFORM node:20-alpine AS frontend-builder @@ -52,8 +55,6 @@ RUN CGO_ENABLED=1 GOOS=linux go build \ -o api ./cmd/api # ---- Final Runtime with Caddy ---- -# Allow pinning Caddy by digest via build-arg -ARG CADDY_IMAGE=caddy:2-alpine FROM ${CADDY_IMAGE} WORKDIR /app