Plugin: updater-replace
Replaces regular expressions or literal text in arbitrary project files. Use it whenever a version string lives in a file that no dedicated updater covers, such as a README badge, a Dockerfile argument, or a source constant.
Installation
Section titled “Installation”Binary
Section titled “Binary”semrel plugin install @semrel/updater-replacesemrel plugin install downloads the binary to .semrel/plugins/ and updates .semrel.lock. Commit .semrel.lock to pin the version for your team.
Docker
Section titled “Docker”Pre-built, signed multi-platform images (linux/amd64, linux/arm64) are published on every release:
docker pull ghcr.io/semrels/updater-replace:latestVerify the image signature with cosign:
cosign verify ghcr.io/semrels/updater-replace:latest \ --certificate-identity-regexp 'https://github.com/SemRels/updater-replace/.github/workflows/release.yml.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comConfiguration
Section titled “Configuration”version: 1plugins: - uses: @semrel/updater-replace phase: pre-tag args: files: README.md,docs/**/*.md ignore: docs/archive/** from: 'version-\d+\.\d+\.\d+' to: 'version-${nextRelease.version}' countMatches: "true"The flat form configures a single rule. files and ignore accept comma-, semicolon-, or newline-separated patterns, including recursive ** globs.
Environment Variables
Section titled “Environment Variables”| Name | Required | Default | Description |
|---|---|---|---|
SEMREL_PLUGIN_FILES | yes | — | File patterns to update. |
SEMREL_PLUGIN_IGNORE | no | — | Patterns excluded from the match set. |
SEMREL_PLUGIN_FROM | yes | — | Go regular expression to search for. |
SEMREL_PLUGIN_TO | no | — | Replacement string with template support. |
SEMREL_PLUGIN_LITERAL | no | false | Treat from as literal text instead of a regular expression. |
SEMREL_PLUGIN_FLAGS | no | — | Go regexp flags: i, m, s, and U. |
SEMREL_PLUGIN_COUNT_MATCHES | no | false | Include match counts in the per-file summary. |
SEMREL_PLUGIN_REPLACEMENTS | no | — | YAML or JSON array describing multiple rules. |
Multiple rules
Section titled “Multiple rules”SemRel maps every args value to a single environment variable, so structured rules are passed as a YAML block scalar:
version: 1plugins: - uses: @semrel/updater-replace phase: pre-tag args: replacements: | - files: ["README.md", "docs/**/*.md"] ignore: ["docs/archive/**"] from: 'version-\d+\.\d+\.\d+' to: 'version-${nextRelease.version}' countMatches: true results: - file: README.md hasChanged: true numMatches: 1 numReplacements: 1 - files: Dockerfile from: '^ARG VERSION=.*$' flags: m to: 'ARG VERSION=${nextRelease.version}'files, ignore, and from accept either a string or a list. Multiple from patterns run in order, and replacement strings use Go regexp expansion, so $1 and ${name} capture references work as expected.
Templates
Section titled “Templates”| Template | Source |
|---|---|
${nextRelease.version} | SEMREL_VERSION / SEMREL_NEXT_VERSION |
${lastRelease.version} | SEMREL_CURRENT_VERSION |
${gitTag} / ${tag} | SEMREL_TAG_NAME |
${channel} / ${branch} | SEMREL_BRANCH |
${date} | Current UTC date (YYYY-MM-DD) |
Version templates always resolve to the bare SemVer value, even when SemRel reports a tag prefix such as v1.4.0.
Release Context Variables
Section titled “Release Context Variables”SEMREL_VERSIONSEMREL_CURRENT_VERSIONSEMREL_TAG_NAMESEMREL_TAG_PREFIXSEMREL_BRANCHSEMREL_DRY_RUN
Behavior
Section titled “Behavior”Every rule is evaluated in memory first, and all results assertions must pass before a single file is written. This prevents partial updates when a regular expression drifts. Writes go to a temporary file in the target directory followed by an atomic rename, preserving the original permission bits and existing CRLF line endings.
In a dry run the plugin still performs matching, templating, and assertion validation, reports the files it would update, and writes nothing. Modified paths are printed to stdout, one per line; diagnostics go to stderr. A missing file match, invalid pattern, failed assertion, or write error exits non-zero.