Skip to content

Managing Plugins

semrel installs plugins as local binaries and resolves them at runtime — no daemon, no global state. The plugin management system gives every team member and every CI runner the exact same binary, at the exact same version.

Installing a plugin project-local

Section titled “Installing a plugin ”
  1. Use the full registry reference

    Every official plugin lives in the @semrel namespace. Always include it:

    Terminal window
    semrel plugin install @semrel/github

    A bare name (github) is only accepted when the matched registry entry has no namespace.

  2. Pin a specific version when needed

    Terminal window
    semrel plugin install @semrel/github@1.2.0
  3. Commit the lock file

    A default install writes .semrel.lock at the repository root automatically. Commit it together with .semrel.yaml so everyone uses the same version.

All naming variants resolve to the same binary on disk — semrel strips the namespace, version, and any category prefix before looking for an executable:

Config entryBinary on disk
uses: githubsemrel-plugin-github
uses: provider-githubsemrel-plugin-github
uses: @semrel/github@1.2.0semrel-plugin-github
uses: github-actionssemrel-plugin-github-actions
uses: condition-github-actionssemrel-plugin-github-actions

.semrel.lock records the exact version and published checksums of every project-local plugin install. It is updated automatically whenever you run semrel plugin install without --plugin-dir.

{
"semrelLockVersion": 1,
"updatedAt": "2026-06-11T09:33:00Z",
"plugins": [
{
"binaryName": "semrel-plugin-github",
"ref": "@semrel/github",
"version": "1.2.0",
"checksums": {
"linux_amd64": "3b4c…",
"linux_arm64": "9f1e…",
"darwin_amd64": "c72a…",
"darwin_arm64": "55d0…",
"windows_amd64": "a81b…",
"windows_arm64": "e3f7…"
}
}
]
}

Checksums are stored for every published platform so semrel plugin restore can verify the binary on any OS/architecture without a registry round-trip.

  • .semrel.yaml configuration — commit
  • .semrel.lock pinned plugin versions — commit
  • Directory.semrel/
    • Directoryplugins/ binary cache — ignored
    • Directoryregistry-cache/ metadata cache — ignored
    • Directorylinux_amd64/ download cache — ignored
    • Directorydarwin_arm64/ download cache — ignored
    • Directorywindows_amd64/ download cache — ignored

Add these entries to your .gitignore:

# semrel — local binaries and caches (do NOT commit)
.semrel/plugins/
.semrel/registry-cache/
.semrel/linux_*/
.semrel/darwin_*/
.semrel/windows_*/
# .semrel.lock at the repo root IS committed

semrel plugin restore reads .semrel.lock, downloads every listed plugin into .semrel/plugins/, skips binaries that are already present, and verifies the checksum for the current platform.

Use this command on CI and after cloning a repository:

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up semrel
run: |
curl -sSL https://semrel.io/install.sh | sh
- name: Restore semrel plugins
run: semrel plugin restore
- name: Release
run: semrel release
env:
SEMREL_PLUGIN_TOKEN: ${{ secrets.GITHUB_TOKEN }}

When semrel looks up a plugin binary, it checks these locations in priority order:

  1. path: in .semrel.yaml — explicit local binary, highest priority. Ideal for development or custom builds.

  2. .semrel/plugins/<binary> — project-local install. Populated by semrel plugin install and semrel plugin restore.

  3. ~/.semrel/plugins/<binary> — user-global install. Shared across all repositories on the machine.

  4. $PATH — system-managed binary. Useful for package-manager installs.


Automatic plugin restore during semrel release

Section titled “Automatic plugin restore during semrel release”

semrel release checks plugin availability before doing anything else. The exact behaviour depends on whether .semrel.lock is committed:

SituationWhat semrel does
All plugins presentContinue immediately — no download needed
Some plugins missing + .semrel.lock existsRun semrel plugin restore automatically, then continue
Some plugins missing, no lock fileAttempt per-plugin auto-install (best-effort, uses latest stable)
$ semrel release
⬇ plugins missing — running semrel plugin restore from .semrel.lock…
✓ restored @semrel/github@1.2.0 → .semrel/plugins/semrel-plugin-github
✓ restored @semrel/github-actions@0.1.0 → .semrel/plugins/semrel-plugin-github-actions
Running condition checks…

Restore from the lock file is a hard operation: if a binary’s checksum does not match, semrel fails immediately rather than silently using a different binary.

If .semrel.lock is absent, semrel still attempts to auto-install each missing plugin individually. Version resolution:

  1. Version from uses:uses: github@1.2.0 pins the version explicitly.
  2. Latest stable — if no version is specified, the newest non-prerelease is downloaded.

Use --plugin-dir to install into a directory other than .semrel/plugins/:

Terminal window
# User-global install (does not update .semrel.lock)
semrel plugin install @semrel/github --plugin-dir ~/.semrel/plugins
# Custom path
semrel plugin install @semrel/github --plugin-dir /opt/semrel/plugins

Plugin Overview CLI Reference Registry ↗