Kai Ole Hartwig
pinup · documentation

Configuration

pinup reads Renovate's configuration language. A repository with a renovate.json keeps it. Switching from Renovate changes no byte in a repository.

  • Three layers: the run's configuration, the repository's file, the presets
  • Merge semantics: Renovate's, measured against it
  • Keys:pinup migrate classifies every one

Three layers

The run's configuration

--config: a file or a local> preset from the platform (local>group/runner, local>group/runner:release-fast). This is the estate's file: rules, custom managers, presets.

The repository's file

PINUP_RUNNER_PROJECT names the runner project when --config is a file

Exactly one of .pinup.yaml, .pinup.yml, .pinup.json, .pinup.jsonc, renovate.json, renovate.json5, .renovaterc and .renovaterc.json. Two of them is an error, not a silent choice: the one that lost would be edited for weeks with no effect. Which is also why that list is not a precedence. Its extends may name the run's file as local><runner-project>; pinup answers that name from the file it was started with, without a fetch, and also the project's old name after the file has moved. That is how an estate changes its runner without touching the repositories.

Presets

Renovate's built-in names (config:recommended, :disableDependencyDashboard …) come from pinup's own preset library, written from observed behaviour, not from Renovate's source. local> presets of other projects are fetched from the platform.

Merge semantics

The rules are Renovate's, measured against it:

Every resolved value keeps its whole origin chain. pinup print-config --config … --explain packageRules[25].automerge shows every source that set a path, winner last. A held update in the plan names the rule the same way.

The keys

pinup migrate --config … classifies every key. Supported means: the key does what it does in Renovate, measured. Partial names the difference. Unsupported means: nothing reads it, and the run says so.

Supported

$schema, addLabels, additionalBranchPrefix, allowedCommands, allowedVersions, automerge, branchPrefix, branchTopic, commitMessageAction, commitMessageExtra, commitMessageLowerCase, commitMessagePrefix, commitMessageSuffix, commitMessageTopic, customDatasources, customManagers, dependencyDashboard, dependencyDashboardApproval, dependencyDashboardTitle, description, enabled, enabledManagers, extends, extractVersion, fetchChangeLogs, groupName, groupSlug, ignoreDeps, ignorePaths, ignoreUnstable, internalChecksFilter, labels, lockFileMaintenance, matchCurrentValue, matchDatasources, matchDepNames, matchDepTypes, matchFileNames, matchManagers, matchPackageNames, matchUpdateTypes, minimumReleaseAge, minimumReleaseAgeBehaviour, osvVulnerabilityAlerts, packageRules, pinDigests, platformAutomerge, postUpgradeTasks, prBodyDefinitions, prBodyNotes, prConcurrentLimit, prHourlyLimit, rangeStrategy, registryUrls, schedule, semanticCommitScope, semanticCommitType, semanticCommits, separateMajorMinor, timezone, versioning, vulnerabilityAlerts – and pinup's own analyze, matchEffective, trustEffective.

Partial

Unsupported

A key not listed here is not read; migrate lists it as unsupported.

pinup's own keys

KeyWhereMeaning
analyzeruleasks an analyzer what actually changed in this dependency's updates; off by default, because it fetches both versions
matchEffectiverulematches the analyzer's label: patch, minor, major, breaking-values; never fires while the label is unknown
trustEffectiverulelets an automerge stand that a matchEffective rule switched on although the declared label is stricter; without it the stricter label wins

Custom managers

customManagers with customType: regex work as in Renovate: RE2 expressions with named groups (depName, currentValue, currentDigest, datasource, versioning, registryUrl, packageName, extractVersion), the *Template keys with a Handlebars subset ({{{x}}}, {{#if}}/{{else}}, {{#if (equals a "b")}}), matchStringsStrategyany and recursive. A captured group beats its template. # renovate: and # pinup: are both read.

Environment

VariableMeaning
PINUP_PLATFORMgitlab (the default) or github; a GitHub token with no GitLab instance in the environment means github
PINUP_GITLAB_URL / CI_SERVER_URLthe GitLab instance
PINUP_GITLAB_TOKEN / GITLAB_TOKENa personal access token (api, write_repository); CI_JOB_TOKEN when none is set (read-only)
PINUP_GITHUB_URL / GITHUB_SERVER_URLthe GitHub host; github.com when empty
PINUP_GITHUB_TOKEN / GITHUB_TOKENa token with repo, or a fine-grained one with contents, pull requests and issues read/write
PINUP_REGISTRY_HOST / CI_REGISTRYthe estate's container registry; the token is exchanged for a pull token there and nowhere else
GITHUB_COM_TOKENfor github-* lookups and release notes, bound to api.github.com
PINUP_GIT_NAME, PINUP_GIT_EMAILwho commits
PINUP_SIGNING_FORMAT, PINUP_SIGNING_KEYopenpgp or ssh and the key; unsigned only with the explicit word none
PINUP_CACHEthe lookup cache (bbolt)
PINUP_ALLOWED_COMMANDSJSON array of anchored patterns a postUpgradeTasks command must match; the runner's decision, never a repository's
PINUP_PLUGIN_ENVvariables a task may see besides PATH, LANG, TZ
PINUP_TASK_NETRCa .netrc written into each task's own HOME; never as a variable
PINUP_EXECUTION_TIMEOUTminutes per task
PINUP_RUNNER_PROJECTthe project whose configuration the repositories include
PINUP_APK_VIEWSapk indexes served natively besides the public Wolfi repository

Checking a configuration: pinup advise

pinup advise resolves a configuration the way a run does and says what should change. Every finding carries its pointer, the layer that wrote the value – file, preset or default – and, where the file owns the value, a fix.

 

pinup advise --config renovate.json --runner 'local>group/pinup-runner'
pinup advise --config renovate.json --plan plan.json      # plus what the runs found
pinup advise --config renovate.json --fix --out fixed.json
CategoryWhat it finds
compatkeys pinup does not read; rules that never fire; a regex with a lookaround; a schedule that does not parse
hygienea value a preset already sets; a preset extended twice; a rule a later one fully shadows
performancean ignorePaths that replaces the inherited list instead of adding to it; a lock refresh with no window
securityan automerge that covers major updates; a registry over HTTP; advisories switched off

With --plan the runs join in: rules no dependency reached, managers that found nothing, a repository whose every update one setting holds.

--fix applies the fixes byte for byte to JSON, JSONC and JSON5. Comments, order and formatting stay. Nothing is written until a gate has passed: the file is resolved before and after, and every line that differs must lie under a pointer a fix declared. A fix that declares nothing must leave the resolution unchanged. Without --out or --write it is a dry run. --skip holds back checks that need a decision. A YAML file is reported, not rewritten.

Every check with its ID, severity and fix is listed in docs/commands.md in the repository.

Next

Back to pinup

The overview: the problem, the fit check, the quickstart, every chapter.

pinup →
Back to pinup

Managers, datasources, versionings

Which files are read, which registries are asked, how versions are ordered.

Read →
Managers, datasources, versionings