Skip to main content

Version updates

Version updates is the hosted-Renovate lane of Dependency updates. Enable it for an org and fremforge opens grouped, reviewable PRs on the schedule defined by your renovate.json: npm, gomod, Terraform providers, Dockerfile base images, Helm charts, and any custom regex pin. Every enrolled organisation’s repositories are run every night; see Cadence.

Vulnerable dependencies found by your scans are the other lane’s job: Security fixes open one pull request per vulnerable package. Until the Security fixes lane takes over for your organisation, hosted Renovate also opens its own security pull requests for OSV advisories, as described below.

Built into the €30/seat plan. No add-on tier, no third-party action minutes, no GitHub-the-company in the data path.

What you get

  • Automatic PRs for outdated dependencies, grouped sensibly, one PR per related package set rather than dozens of one-line bumps.
  • Vulnerability-triggered PRs for published security advisories (OSV), opened by the next run rather than waiting for your schedule, and not held back by the release-age wait described under Platform policy (for npm, see the one exception there). Once the Security fixes lane takes over for an organisation, these are switched off there, so a fix is only ever proposed once.
  • Renovate Dependency Dashboard issue in each repo, see status at a glance.
  • Full Renovate config schema, every option at docs.renovatebot.com works on fremforge unchanged. Your rules are applied on top of the platform policy.
  • Per-tenant bot user, <org>-fremforge-bot-deps, scoped to your org only, token never crosses tenant boundaries. Security fixes use the same bot.
  • EU-sovereign, runs on T Cloud Public CCE; no third-party SaaS in the data path.

Enabling

  1. Open Security › Fix › Dependency updates (or Build & deploy › Dependency updates) and go to Version updates.
  2. Enable hosted Renovate.
  3. fremforge provisions a per-tenant bot user, <org>-fremforge-bot-deps, and grants it write access to your org’s repos.
  4. The repositories are picked up by the next nightly run, or at once with Run now; pull requests then follow the schedule in your renovate.json.

Enabling also gives the organisation the default Security fixes settings: fix pull requests on click, waiting for review.

The bot user is fremforge-managed. You don’t need to create it, rotate its credentials, or worry about lost passwords. The token is platform-managed and rotated automatically.

Disabling

  1. Security › Fix › Dependency updates → Version updates → disable hosted Renovate.
  2. fremforge revokes the bot’s token immediately and removes the bot from your org, unless Security fixes are set to an automatic mode: then the bot stays, for security fixes only.
  3. PRs already opened by Renovate stay open. Merge or close them as you would any other PR.
  4. The org’s renovate.json stays in your repos; fremforge doesn’t touch it.

Re-enabling provisions a fresh bot. The previous bot username is tombstoned (not reused) so audit history stays clean.

Platform policy

Every run starts from fremforge’s policy, and your renovate.json is applied on top of it.

  • Cadence. Every enrolled organisation’s repositories are queued for a run every night (from 02:30 UTC); a repository that ran in the last 4 hours is skipped. A schedule in your renovate.json still limits when routine pull requests are opened. Security updates (vulnerability alerts) ignore that schedule and the release-age wait, and are opened by the next run after the advisory is published. Run now starts a run out of cycle.
  • Release-age wait. A routine update is proposed only once the new version is as old as your organisation’s release age (3 days unless an owner changed it), so a malicious or broken release that is pulled within days never reaches you. Registries that publish no release date get no wait. Security updates skip the wait, with one exception for npm: a fix version younger than the release age is offered only when npm’s advisory data lists it as fixing the version you have. A fix that data does not list waits like a routine update.
  • The wait covers your lockfile too. Renovate proposes a version, and your package manager then resolves the lockfile, including any new transitive dependency. For npm, pnpm and Yarn 1, that resolution goes through fremforge’s release-age view of the npm registry, so a range bump cannot lock a version younger than 3 days. The view keeps 3 days for every organisation; with a longer release age, the check below holds the pull request until the lockfile is old enough. Your own .npmrc is still applied after it, so your private scopes and any registry= line of yours take precedence. Yarn 2+ reads .yarnrc.yml instead and is not covered by the view; the check below still holds those PRs.
  • fremforge/release-age check. Every pull request gets this check, and it is a required branch-protection check. On a dependency-update PR it stays pending, reading “Waiting until …”, until every version the lockfile resolves is as old as your release age. It then turns green on its own within minutes, without a new push, and auto-merge waits for it. Security fixes are not held. On a PR opened by a person, fresh versions are reported but do not hold the PR. Setting the scanner to off for an org or repo removes the check from branch protection within the hour.
  • Auto-merge. Patch, pin and digest updates auto-merge on green CI by default. Minor updates auto-merge if you switch that on in the policy settings. Major updates always wait for your approval on the Dependency Dashboard.
  • High-blast-radius packages. About 30 auth, crypto, database, ORM and cloud-KMS packages (for example jsonwebtoken, jose, bcrypt, pg, redis, drizzle-orm, Prisma) never auto-merge a routine update; the PR waits for review. OpenID libraries may auto-merge a patch but never a minor or major.
  • Security updates. Whether hosted Renovate’s own security PRs auto-merge on green CI is the When fixes merge setting of Security fixes: Merge when checks pass or Wait for review (the default). Organisations that had the former Security updates auto-merge switched on, which was the default for every enrolled organisation, were moved to Merge when checks pass, so nothing changed for them. With it, a security PR auto-merges for every package, the high-blast-radius ones included: those are the libraries you most want patched quickly. See Merging.
  • Merge window. An org admin can limit when Renovate PRs are armed to merge, as whole UTC hours on chosen weekdays (merge_window in PUT /_app/api/v1/orgs/{org}/dependency-updates/version-updates/settings). Outside the window no Renovate PR is armed, and arms the bot made are cancelled when the window closes; an arm a person made is left alone. A repository with an open issue labelled release-freeze is never armed.
  • Known-exploited fixes. A security update for a CVE that is exploited in the wild (listed by ENISA’s EU Vulnerability Database or CISA’s Known Exploited Vulnerabilities catalogue, checked daily) is opened before every other update in the run, is not held back by the PR limits, and carries the known-exploited label (when your repository has that label) and a note in the PR description. It is also armed outside the merge window, so it merges as soon as its checks pass. Only the window is skipped: a PR is armed outside it only if it would have been armed inside it, and the release freeze, a person cancelling the auto-merge and your required checks all still apply.
  • Your rules win. Rules in your renovate.json are applied after this policy, so an automerge: true rule there overrides it, including the review hold on high-blast-radius packages. If you add such a rule, exclude those packages from it (see the example below).

Settings

An owner sets the lane’s policy on the page, or with PUT /_app/api/v1/orgs/{org}/dependency-updates/version-updates/settings (scope dependency-updates:write). Every field is optional; one that is left out keeps its value, and an unknown field is refused with unknown-field.

SettingAPI fieldDefault
Hosted Renovate runsenabledtrue
Auto-merge patch, pin and digest updatesautomerge_patchtrue
Auto-merge minor updatesautomerge_minorfalse
Major updates need approval on the Dependency Dashboardmajor_approvaltrue
Schedule override (Renovate schedule text)schedulenone
Pull requests per hourpr_hourly_limit2
Open pull requests at oncepr_concurrent_limit5
Merge windowmerge_windownone

GET on the same path returns the same fields, in the same snake_case spelling. security_automerge is not a field here: whether security PRs merge themselves is the Security fixes merge setting, and sending security_automerge to this path is refused with a message saying so.

Configuring

Per-repo configuration is via renovate.json in the repo root. Without it, Renovate uses sensible defaults, which is usually fine for the first month while you’re seeing what kinds of PRs roll in.

A minimal starter:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended", ":dependencyDashboard"],
  "schedule": ["before 4am on the first day of the month"]
}

A more opinionated config that groups OpenTelemetry packages, auto-merges patch and lockfile bumps, and requires human review for major bumps:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended", ":dependencyDashboard", ":semanticCommits"],
  "timezone": "Europe/Copenhagen",
  "schedule": ["before 4am on the first day of the month"],
  "vulnerabilityAlerts": {
    "labels": ["security"],
    "schedule": ["at any time"]
  },
  "packageRules": [
    {
      "matchPackagePatterns": ["^@opentelemetry/"],
      "groupName": "opentelemetry"
    },
    {
      "matchUpdateTypes": ["patch", "pin", "digest", "lockFileMaintenance"],
      "automerge": true,
      "platformAutomerge": true
    },
    {
      "matchUpdateTypes": ["major"],
      "automerge": false,
      "labels": ["major-bump"]
    }
  ]
}

The automerge rule in this example is applied after the platform policy, so it would also auto-merge the auth, crypto and database packages fremforge otherwise holds for review. To keep those manual, exclude them from the rule, for example "matchPackageNames": ["*", "!pg", "!jose", "!bcrypt"].

The full Renovate configuration reference is at docs.renovatebot.com/configuration-options/.

What gets bumped

Renovate auto-detects most ecosystems without configuration. Auto-detected ecosystems on fremforge:

  • npm / pnpm / yarn, package.json + lockfile maintenance
  • Go modules, go.mod
  • OpenTofu / Terraform, provider versions in versions.tf
  • Dockerfile, FROM lines, with digest pinning option
  • Helm, chart versions in values.yaml and Chart.yaml
  • Custom regex pins, for any version string in any file (great for pinning shell-script-installed binaries)
  • Python, pyproject.toml, requirements*.txt, Pipfile and Poetry. Hash-pinned requirements compiled with uv pip compile or pip-compile are relocked as a whole; see Compiled Python requirements.

For the full ecosystem matrix see docs.renovatebot.com/modules/manager/.

Compiled Python requirements

A requirements*.txt written by uv pip compile or pip-compile pins every package, often with --hash lines. Some bumps also need another pin to move. For example, pydantic pins pydantic-core to one exact version. When the lock’s header names the command that wrote it, hosted Renovate re-runs that command with --upgrade-package, so the update pull request contains the whole relocked file: the bumped package, every pin it moves, and their hashes. Without the relock, the PR changes one line and pip install --require-hashes refuses it.

Hosted Renovate does this for any requirements*.txt whose header holds a compile command, in every organisation. You do not need to configure anything, as long as the header follows Renovate’s rules:

  • Use long option names, and join each value with =, for example --output-file=requirements.txt, --python-version=3.11, --extra=dev and --group=dev. uv writes the command into the header exactly as you typed it. Renovate refuses -o requirements.txt and --python-version 3.11, and then leaves that lock alone.
  • Name the source file, for example uv pip compile pyproject.toml .... A header without a source file (for example uv pip compile --group render ...) is not relocked.
  • Give every direct dependency a version constraint. A dependency written with no version at all ("httpx") is not relocked; its bump changes only its own line. A floor such as "httpx>=0.28" is enough.

A header that works:

# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml --extra=dev --universal --python-version=3.11 --generate-hashes --output-file=requirements-dev.txt

Renovate keeps --python-version when it relocks, so set it to the oldest Python you support. The relocked file is the same file your own compile would produce, and it records no index URL.

The relock resolves against public PyPI, the same index Renovate uses to find the new version, unless the header or your pyproject.toml names another index. A hand-written requirements.txt with no compile header is updated one line at a time, as before.

Out-of-cycle runs

Need a Renovate run before the next scheduled cycle (e.g. you just published a new renovate.json and want to see what it produces)?

  1. Security › Fix › Dependency updates → Run now.
  2. Rate-limited to one out-of-cycle run per hour per org.
  3. Results appear under Activity within a few minutes.

Vulnerability-triggered PRs already route out-of-cycle automatically. You don’t need to click “Run now” when a new CVE drops; Renovate’s own vulnerability scheduler handles it.

Cadence customisation

Renovate’s schedule field accepts cron-shaped expressions. A few common patterns:

  • ["before 4am on the first day of the month"], once a month. (fremforge’s default is no schedule: a run every night, and pull requests may open on any run.)
  • ["before 4am every weekday"], daily on weekdays.
  • ["after 9pm and before 5am"], only outside business hours.
  • [], never; rely on vulnerability-triggered runs only.

The vulnerabilityAlerts.schedule field overrides for security PRs:

{
  "vulnerabilityAlerts": {
    "schedule": ["at any time"]
  }
}

Cost

Included in the €30/seat plan. No metering, no per-PR charge, no separate runner-minute line.

For comparison: GitHub’s Dependabot is free, but Dependabot Updates that run on Actions consume your Actions minutes. fremforge’s hosted Renovate runs on fremforge-managed CCE infrastructure (separate from your CI runner pool, so it never consumes runner minutes). That’s the practical difference.

Why Renovate, not Dependabot

Renovate is the OSS tool we run against our own repositories, same config, same cadence, same PR shape, and chose to expose as the hosted dependency-updates feature. Renovate has native Forgejo support since v37; its config schema is broader than Dependabot’s; it works with custom regex pins which Dependabot doesn’t. Most teams who use both prefer Renovate.

You can also self-host Renovate against your own fremforge repos without enrolling in the hosted version. Just drop a renovate.json and run Renovate yourself in CI. The hosted version is the convenience layer; the OSS Renovate config you write is identical either way.

Private registries

Add a read credential under Security › Fix › Dependency updates → Version updates → Private registries:

  1. Label — a name for your own reference (e.g. “GitHub Packages”).
  2. Type — npm, docker, or git (a private git host for module/tag lookups, e.g. a private Terraform module source).
  3. Host / registry URL — the registry host (e.g. npm.pkg.github.com) or an https:// URL prefix. Loopback / metadata / private-range hosts are rejected.
  4. Username — only for Docker basic-auth; leave blank for token-only npm and git.
  5. Token / password — a read-scoped token for that registry.

The token is stored encrypted (AES-256-GCM), used only for your own Renovate runs, never returned by the API, and — unlike an Actions secret — never exposed to your CI workflows. Renovate authenticates that registry on the next run. Remove a credential any time; lookups for its packages will start failing again until you re-add it.

This is the fremforge equivalent of GitHub’s Dependabot registry secrets.

Cross-references