diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml
new file mode 100644
index 0000000..3565f32
--- /dev/null
+++ b/.github/workflows/actionlint.yml
@@ -0,0 +1,22 @@
+name: Actionlint
+
+on:
+ pull_request:
+ branches: [master]
+ push:
+ branches: [master]
+
+permissions:
+ contents: read
+
+jobs:
+ actionlint:
+ name: Lint GitHub Workflows
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Run actionlint
+ uses: reviewdog/action-actionlint@v1
diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml
new file mode 100644
index 0000000..0430568
--- /dev/null
+++ b/.github/workflows/pr-title.yml
@@ -0,0 +1,33 @@
+name: PR Title Check
+
+on:
+ pull_request_target:
+ types: [opened, edited, reopened, synchronize]
+ branches: [master]
+
+permissions:
+ pull-requests: read
+
+jobs:
+ semantic-pr-title:
+ name: Validate PR Title
+ if: github.event.pull_request.user.login != 'renovate[bot]' && github.event.pull_request.user.login != 'dependabot[bot]'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check PR title follows Conventional Commits
+ uses: amannn/action-semantic-pull-request@v5
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ types: |
+ feat
+ fix
+ chore
+ docs
+ refactor
+ test
+ build
+ ci
+ perf
+ revert
diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml
new file mode 100644
index 0000000..3d57dd0
--- /dev/null
+++ b/.github/workflows/renovate.yml
@@ -0,0 +1,26 @@
+name: Renovate
+
+on:
+ schedule:
+ - cron: '0 5 * * 1'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ pull-requests: write
+ issues: write
+
+jobs:
+ renovate:
+ name: Run Renovate Bot
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Run Renovate
+ uses: renovatebot/github-action@v41
+ with:
+ configurationFile: renovate.json
+ token: ${{ secrets.RENOVATE_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/README.md b/README.md
index 3fc1979..ca7828a 100644
--- a/README.md
+++ b/README.md
@@ -107,6 +107,23 @@ The CLI uses pinned, tested versions for all dependencies:
| Playwright | ^1.49.1 |
| TypeScript | ^5.7.2 |
+## Automated dependency updates
+
+This repo now uses Renovate to auto-update dependencies (including template manifests under `src/templates/overlays/**/manifest.json`) on a weekly schedule.
+
+### One-time setup
+
+1. Create a fine-grained GitHub PAT with repository `contents`, `pull requests`, and `issues` write access.
+2. Add it as repository secret: `RENOVATE_TOKEN`.
+3. Enable repository auto-merge in GitHub settings.
+4. Protect `master` and require CI checks before merge.
+
+Workflow file: `.github/workflows/renovate.yml`
+Config file: `renovate.json`
+
+Behavior:
+- All dependency updates (major, minor, patch) auto-merge after checks pass.
+
## Screenshot
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..25b7f7b
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,36 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": ["config:recommended"],
+ "labels": ["dependencies"],
+ "schedule": ["before 6am on monday"],
+ "rangeStrategy": "bump",
+ "dependencyDashboard": true,
+ "lockFileMaintenance": {
+ "enabled": true,
+ "automerge": true,
+ "automergeType": "pr",
+ "platformAutomerge": true
+ },
+ "customManagers": [
+ {
+ "customType": "regex",
+ "managerFilePatterns": [
+ "/^src\\/templates\\/overlays\\/.*\\/manifest\\.json$/"
+ ],
+ "matchStrings": [
+ "(?m)^\\s{4}\"(?[^\"\\s]+)\":\\s*\"(?[~^]?\\d+\\.\\d+\\.\\d(?:[-+][0-9A-Za-z.-]+)?)\",?$"
+ ],
+ "datasourceTemplate": "npm",
+ "versioningTemplate": "npm"
+ }
+ ],
+ "packageRules": [
+ {
+ "description": "Automerge all dependency updates after checks pass",
+ "matchUpdateTypes": ["major", "minor", "patch", "pin", "digest"],
+ "automerge": true,
+ "automergeType": "pr",
+ "platformAutomerge": true
+ }
+ ]
+}