-
Notifications
You must be signed in to change notification settings - Fork 0
chore(renovate): add org-wide shared Renovate config #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| name: Dependency Review | ||
|
|
||
| # Fails a PR that introduces a dependency with a known advisory. Renovate tells | ||
| # you about vulnerabilities you already have; this catches the ones a PR is | ||
| # about to add. Public repos only - the underlying API needs GitHub Advanced | ||
| # Security on private repos. | ||
| # | ||
| # Call it from a repo like this: | ||
| # | ||
| # jobs: | ||
| # dependency-review: | ||
| # uses: EduIDE/.github/.github/workflows/dependency-review.yml@main | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| fail-on-severity: | ||
| description: "Minimum severity that fails the check (low, moderate, high, critical)" | ||
| required: false | ||
| default: high | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| review: | ||
| name: Dependency review | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/dependency-review-action@v4 | ||
| with: | ||
| fail-on-severity: ${{ inputs.fail-on-severity }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,266 @@ | ||
| { | ||
| "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
| "description": [ | ||
| "EduIDE org-wide Renovate policy. Single source of truth for every repo.", | ||
| "Consume it with: { \"extends\": [\"local>EduIDE/.github:renovate-config\"] }", | ||
| "Policy: no automerge anywhere. Security fixes raised immediately, everything else batched Monday morning.", | ||
| "See renovate/README.md in this repo for how to change or test this file." | ||
| ], | ||
|
|
||
| "extends": [ | ||
| "config:recommended", | ||
| ":semanticCommitTypeAll(chore)", | ||
| "abandonments:recommended", | ||
| "customManagers:githubActionsVersions", | ||
| "customManagers:dockerfileVersions" | ||
| ], | ||
|
|
||
| "timezone": "Europe/Berlin", | ||
| "schedule": ["* 0-6 * * 1"], | ||
|
|
||
| "dependencyDashboard": true, | ||
| "dependencyDashboardTitle": "Renovate Dependency Dashboard", | ||
| "dependencyDashboardLabels": ["dependencies", "renovate"], | ||
| "dependencyDashboardOSVVulnerabilitySummary": "unresolved", | ||
|
|
||
| "labels": ["dependencies"], | ||
| "semanticCommits": "enabled", | ||
|
|
||
| "automerge": false, | ||
| "platformAutomerge": false, | ||
|
|
||
| "prConcurrentLimit": 5, | ||
| "prHourlyLimit": 2, | ||
| "branchConcurrentLimit": 8, | ||
|
|
||
| "minimumReleaseAge": "5 days", | ||
| "internalChecksFilter": "strict", | ||
|
|
||
| "rangeStrategy": "auto", | ||
| "postUpdateOptions": ["gomodTidy"], | ||
| "separateMajorMinor": true, | ||
| "separateMultipleMajor": false, | ||
| "separateMinorPatch": false, | ||
|
|
||
| "pinDigests": false, | ||
| "updatePinnedDependencies": true, | ||
| "configMigration": true, | ||
|
|
||
| "osvVulnerabilityAlerts": true, | ||
| "vulnerabilityAlerts": { | ||
| "description": "Security fixes bypass the Monday schedule and the release-age quarantine. Rate limits are bypassed unconditionally by Renovate itself.", | ||
| "enabled": true, | ||
| "schedule": [], | ||
| "minimumReleaseAge": null, | ||
| "dependencyDashboardApproval": false, | ||
| "prCreation": "immediate", | ||
| "commitMessagePrefix": "fix(security):", | ||
| "addLabels": ["security"], | ||
| "automerge": false | ||
| }, | ||
|
|
||
| "lockFileMaintenance": { | ||
| "description": "Monthly sweep so in-range (caret) updates still reach the lockfiles. Load-bearing: with rangeStrategy auto, this is the only path for them.", | ||
| "enabled": true, | ||
| "schedule": ["* 0-6 1 * *"], | ||
| "minimumReleaseAge": null, | ||
| "commitMessageAction": "Refresh", | ||
| "automerge": false | ||
| }, | ||
|
|
||
| "ignorePaths": [ | ||
| "**/node_modules/**", | ||
| "**/bower_components/**", | ||
| "**/vendor/**", | ||
| "**/__tests__/**", | ||
| "**/__fixtures__/**", | ||
| "**/.worktrees/**", | ||
| "**/.vscode-test/**", | ||
| "**/.vscode-test-web/**", | ||
| "**/.docusaurus/**", | ||
| "**/dist/**", | ||
| "**/build/**", | ||
| "**/out/**" | ||
| ], | ||
|
|
||
| "customManagers": [ | ||
| { | ||
| "customType": "regex", | ||
| "description": "EduIDE-deployment pins the student IDE images as plain YAML list items under preloading.images. The helm-values manager only understands image dicts and scalars, so without this they would never be updated.", | ||
| "managerFilePatterns": ["/^deployments/.+/values\\.ya?ml$/"], | ||
| "matchStrings": [ | ||
| "-\\s+(?<depName>ghcr\\.io/[^\\s:\"']+):(?<currentValue>[^\\s\"']+)" | ||
| ], | ||
| "datasourceTemplate": "docker" | ||
| }, | ||
| { | ||
| "customType": "regex", | ||
| "description": "theiaPlugins in EduIDE/package.json pins plugin tarballs by GitHub release URL. No built-in manager reads custom manifest keys.", | ||
| "managerFilePatterns": ["/(^|/)package\\.json$/"], | ||
| "matchStrings": [ | ||
| "https://github\\.com/(?<depName>[^/\"]+/[^/\"]+)/releases/download/(?<currentValue>[^/\"]+)/" | ||
| ], | ||
| "datasourceTemplate": "github-releases" | ||
| } | ||
| ], | ||
|
|
||
| "packageRules": [ | ||
| { | ||
| "description": "Never bump engines.* - these are compatibility floors, not dependencies.", | ||
| "matchManagers": ["npm"], | ||
| "matchDepTypes": ["engines"], | ||
| "enabled": false | ||
| }, | ||
| { | ||
| "description": "@types/vscode must stay in lockstep with engines.vscode - raise both by hand.", | ||
| "matchPackageNames": ["@types/vscode"], | ||
| "enabled": false | ||
| }, | ||
| { | ||
| "description": "Never bump the go / toolchain directive in go.mod.", | ||
| "matchManagers": ["gomod"], | ||
| "matchDepTypes": ["golang", "toolchain"], | ||
| "enabled": false | ||
| }, | ||
| { | ||
| "description": "Anything on a -SNAPSHOT is built in-repo, not resolved from a registry.", | ||
| "matchCurrentValue": "/-SNAPSHOT$/", | ||
| "enabled": false | ||
| }, | ||
| { | ||
| "description": "Internal Theia Cloud Java modules are reactor modules, not external deps.", | ||
| "matchDatasources": ["maven"], | ||
| "matchPackageNames": ["/^org\\.eclipse\\.theia\\.cloud:/"], | ||
| "enabled": false | ||
| }, | ||
| { | ||
| "description": "Pin / digest / rollback updates have no release timestamp, so exempt them from the quarantine.", | ||
| "matchUpdateTypes": ["pin", "pinDigest", "digest", "rollback"], | ||
| "minimumReleaseAge": null | ||
| }, | ||
|
|
||
| { | ||
| "description": "All GitHub Actions in one PR.", | ||
| "matchManagers": ["github-actions"], | ||
| "matchUpdateTypes": ["minor", "patch", "digest", "pin"], | ||
| "groupName": "github actions", | ||
| "groupSlug": "github-actions", | ||
| "semanticCommitType": "ci", | ||
| "addLabels": ["github-actions"] | ||
| }, | ||
| { | ||
| "description": "All non-major npm devDependencies in one PR.", | ||
| "matchManagers": ["npm"], | ||
| "matchDepTypes": ["devDependencies", "optionalDependencies"], | ||
| "matchUpdateTypes": ["minor", "patch", "pin"], | ||
| "groupName": "npm dev dependencies", | ||
| "groupSlug": "npm-dev", | ||
| "addLabels": ["javascript"] | ||
| }, | ||
| { | ||
| "description": "All non-major npm runtime dependencies in one PR.", | ||
| "matchManagers": ["npm"], | ||
| "matchDepTypes": ["dependencies", "peerDependencies", "resolutions", "overrides"], | ||
| "matchUpdateTypes": ["minor", "patch", "pin"], | ||
| "groupName": "npm dependencies", | ||
| "groupSlug": "npm-prod", | ||
| "addLabels": ["javascript"] | ||
| }, | ||
| { | ||
| "description": "All non-major JVM dependencies in one PR.", | ||
| "matchManagers": ["maven", "maven-wrapper", "gradle", "gradle-wrapper"], | ||
| "matchUpdateTypes": ["minor", "patch"], | ||
| "groupName": "java dependencies", | ||
| "groupSlug": "java", | ||
| "addLabels": ["java"] | ||
| }, | ||
| { | ||
| "description": "All non-major Go modules in one PR.", | ||
| "matchManagers": ["gomod"], | ||
| "matchUpdateTypes": ["minor", "patch", "digest"], | ||
| "groupName": "go modules", | ||
| "groupSlug": "gomod", | ||
| "addLabels": ["go"] | ||
| }, | ||
| { | ||
| "description": "Container base images from Dockerfiles and compose files in one PR.", | ||
| "matchManagers": ["dockerfile", "docker-compose"], | ||
| "matchUpdateTypes": ["minor", "patch", "digest", "pin"], | ||
| "groupName": "container base images", | ||
| "groupSlug": "docker", | ||
| "addLabels": ["docker"] | ||
| }, | ||
| { | ||
| "description": "Helm chart dependencies from Chart.yaml in one PR.", | ||
| "matchManagers": ["helmv3", "helmfile"], | ||
| "matchUpdateTypes": ["minor", "patch"], | ||
| "groupName": "helm charts", | ||
| "groupSlug": "helm", | ||
| "addLabels": ["helm"] | ||
| }, | ||
| { | ||
| "description": "Image tags in values.yaml decide what actually runs - keep them apart from chart dependency bumps so one can be reverted without the other. Matched by path as well as manager, because the preloading.images list is picked up by a custom regex manager and must land in the same group.", | ||
| "matchManagers": ["helm-values"], | ||
| "matchUpdateTypes": ["minor", "patch", "digest", "pin"], | ||
| "groupName": "deployed image tags", | ||
| "groupSlug": "helm-values", | ||
| "addLabels": ["helm", "deployment"] | ||
| }, | ||
| { | ||
| "description": "The preloading.images list entries, same group as the rest of the deployed image tags.", | ||
| "matchFileNames": ["deployments/**"], | ||
| "matchUpdateTypes": ["minor", "patch", "digest", "pin"], | ||
| "groupName": "deployed image tags", | ||
| "groupSlug": "helm-values", | ||
| "addLabels": ["helm", "deployment"] | ||
|
Comment on lines
+209
to
+215
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect deployment files that could match the path-only rule.
fd --type f . | rg '^deployments/.+/(Chart\.ya?ml|package\.json|Dockerfile.*|values\.ya?ml)$' || true
# Validate the adjusted configuration with the Renovate version pinned in CI.
npx --yes --package renovate@44.46.7 -- \
renovate-config-validator --strict renovate-config.jsonRepository: EduIDE/.github Length of output: 1841 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- renovate-config.json relevant ranges ---'
sed -n '1,125p' renovate-config.json
sed -n '180,225p' renovate-config.json
printf '%s\n' '--- deployment files ---'
fd --type f . | rg '(^|/)deployments/|(^|/)(Chart\.ya?ml|values\.ya?ml|Dockerfile[^/]*)$' || true
printf '%s\n' '--- manager and grouping references ---'
rg -n -C 3 '"custom\.regex"|"matchManagers"|"matchDatasources"|"groupName"|"groupSlug"|"matchFileNames"' renovate-config.jsonRepository: EduIDE/.github Length of output: 12096 🌐 Web query:
💡 Result: In Renovate, packageRules follow a specific evaluation and merge process [1]. When multiple packageRules match a single dependency, Renovate evaluates all of them rather than stopping at the first match [1][2]. The configurations from all matching rules are merged together into a single effective configuration for that dependency [1][2]. The order of your packageRules is critical because they are applied sequentially [1]. While all matching rules are applied, later rules can override configuration options from earlier ones if both rules specify the same option [1][2]. Regarding merge behavior: - Mergeable Options: For configuration options defined as "mergeable" (typically array-based fields like addLabels or allowedVersions), values from all matching rules are combined [3][2]. - Non-Mergeable Options: For options that are not mergeable, a later matching rule will overwrite the value set by an earlier rule [3][2]. Because of this, it is recommended to order your packageRules with the least important rules at the top and the most specific or important rules at the bottom, ensuring that high-priority rules correctly override general settings [1]. When using groupName, it behaves like other configuration options within a packageRule [4]. If multiple matching rules specify different groupName values, the last matching rule that defines a groupName will determine the final group name for that dependency [1][2]. Citations:
🌐 Web query:
💡 Result: In Renovate, matchFileNames is a configuration option used within packageRules to selectively apply rules based on the path of the package file being processed [1]. Key points regarding matchFileNames: Purpose: It allows you to target specific directories or files for your packageRules [1]. For example, if you want to apply specific dependency update behavior only to files located within a charts/ directory, you can set "matchFileNames": ["charts/"] [1]. Glob Patterns: The option accepts glob patterns [1]. These patterns are used to match the file paths relative to the repository root [1]. Integration with BumpVersions: It is frequently used in conjunction with the bumpVersions configuration, which allows for manual version bumping of files that are not automatically managed by a standard package manager [1]. In this context, you can define filePatterns using variables like {{packageFileDir}} to dynamically target files relative to the identified package file [1]. Example usage: { "packageRules": [ { "matchFileNames": ["charts/"], "bumpVersions": [ { "filePatterns": ["{{packageFileDir}}/Chart.{yaml,yml}"], "matchStrings": ["version:\s(?[^\\s]+)"] } ] } ] } This configuration ensures that the defined bumpVersions logic only applies when the matched package file is located under the charts/ directory [1]. Citations: Restrict this rule to Docker image dependencies. A non-major 🤖 Prompt for AI Agents |
||
| }, | ||
| { | ||
| "description": "Tool versions pinned via '# renovate:' comments in workflows and Dockerfiles ride along with their ecosystem group.", | ||
| "matchManagers": ["custom.regex"], | ||
| "matchFileNames": [".github/workflows/**", "**/Dockerfile*", "**/*.Dockerfile*"], | ||
| "matchUpdateTypes": ["minor", "patch"], | ||
| "groupName": "pinned tool versions", | ||
| "groupSlug": "tool-versions", | ||
| "addLabels": ["tooling"] | ||
| }, | ||
| { | ||
| "description": "Terraform providers, modules and helm_release charts in one PR.", | ||
| "matchManagers": ["terraform", "terraform-version"], | ||
| "matchUpdateTypes": ["minor", "patch"], | ||
| "groupName": "terraform", | ||
| "groupSlug": "terraform", | ||
| "addLabels": ["terraform"] | ||
| }, | ||
|
|
||
| { | ||
| "description": "Majors get their own PR, and only appear once a human ticks the box on the Dependency Dashboard.", | ||
| "matchUpdateTypes": ["major"], | ||
| "dependencyDashboardApproval": true, | ||
| "minimumReleaseAge": "14 days", | ||
| "addLabels": ["major"] | ||
| }, | ||
|
|
||
| { | ||
| "description": "Eclipse Theia is a monorepo Renovate does not know about - these must move as one, majors included.", | ||
| "matchPackageNames": ["@theia/**", "@eclipse-theia/**", "@eclipse-theiacloud/**"], | ||
| "groupName": "eclipse theia", | ||
| "groupSlug": "theia", | ||
| "dependencyDashboardApproval": true, | ||
| "addLabels": ["theia"] | ||
| }, | ||
| { | ||
| "description": "Quarkus platform BOM and extensions must move as one.", | ||
| "matchDatasources": ["maven"], | ||
| "matchPackageNames": ["/^io\\.quarkus[.:]/"], | ||
| "groupName": "quarkus", | ||
| "groupSlug": "quarkus", | ||
| "addLabels": ["java"] | ||
| }, | ||
| { | ||
| "description": "First-party EduIDE artifacts follow our own release train - no supply-chain quarantine.", | ||
| "matchPackageNames": ["ghcr.io/eduide/**", "theiacloud/**"], | ||
| "minimumReleaseAge": null, | ||
| "addLabels": ["eduide"] | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
| "extends": ["local>EduIDE/.github:renovate-config"] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: EduIDE/.github
Length of output: 3818
🌐 Web query:
GitHub actions/checkout v4 persist-credentials default local git config GITHUB_TOKEN official README💡 Result:
In GitHub Actions, the actions/checkout@v4 action uses a default value of true for the persist-credentials input [1][2]. When this option is enabled (the default), the action configures the authentication token (GITHUB_TOKEN) or SSH key in the local git configuration [3][1]. This allows subsequent steps in your job to run authenticated git commands against the repository [3][4]. For security, the action automatically removes this token during the post-job cleanup process [3][5]. If you wish to prevent the action from storing these credentials in the local git configuration, you can explicitly set persist-credentials to false in your workflow file [3][4].
Citations:
🌐 Web query:
GitHub Actions workflow permissions contents read GITHUB_TOKEN official documentation reusable workflow permissions💡 Result:
In GitHub Actions, the GITHUB_TOKEN is an automatically generated, short-lived token used to authenticate API requests within a workflow [1][2]. Its permissions can be explicitly controlled using the permissions key at either the workflow or job level [3][2][4]. Key aspects of managing GITHUB_TOKEN permissions: 1. Permission Levels: You can set permissions to read, write, or none for various scopes (e.g., contents, issues, packages) [5][2]. If the permissions key is defined, any scope not explicitly listed is set to none [5][2][4]. If it is not defined, the workflow defaults to the repository or organization settings [6]. 2. Reusable Workflows: - Token Limitation: The GITHUB_TOKEN granted to a reusable workflow is capped by the permissions explicitly set in the calling workflow job [7][8]. The called workflow cannot elevate permissions beyond those granted by the caller [7][9]. - Default Behavior: If the calling job does not specify permissions, the called workflow receives the default GITHUB_TOKEN permissions [7]. - Best Practice: To avoid 403 "Resource not accessible" errors, you should grant the necessary write permissions in the caller job (e.g., contents: write) and ensure the reusable workflow also declares the required permissions in its own job definition [8]. This ensures that the effective token has the minimum necessary privileges while adhering to the principle of least privilege [8][3]. 3. Contents Permission: Specifying contents: read allows actions to clone and fetch the repository, while contents: write is required for tasks such as pushing code, creating releases, or modifying files [5][6]. In summary, when using reusable workflows, always explicitly define the required permissions in the calling job to ensure the invoked workflow has sufficient access, while keeping the scope as restrictive as possible [8][6].
Citations:
Set
persist-credentials: falseon both affected checkout steps.actions/checkout@v4storesGITHUB_TOKENin.git/configby default. The subsequentnpxcommand and dependency-review action can read this configuration if compromised. The workflows declarecontents: read; retain least-privilege permissions in callers of the reusable workflow.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 17-22: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
📍 Affects 2 files
.github/workflows/ci.yml#L17-L17(this comment).github/workflows/dependency-review.yml#L31-L31🤖 Prompt for AI Agents
Source: Linters/SAST tools