npm publish.
Writing a shift package
A shift package is a regular npm package with abin entry. When fleetshift runs your
shift against a target repository, it:
- Clones the target repository into a working directory.
- Sets
process.cwd()to the cloned repo. - Runs your binary.
Minimal example
Directory structure:chmod +x bin/my-shift
Package naming rules
- All packages must use the
@fleetshift/scope:@fleetshift/my-shift - The unscoped part must be lowercase and can only contain letters, digits,
.,_,- - No protocol or path specifiers (
github:,https://,file:)
Exit codes
Publishing to your Portal registry
Portal exposes an npm registry proxy that your shift packages are published through. This works the same way as publishing custom plugins — you use your existing Backstage service token to authenticate.Step 1: Configure npm authentication
Add an.npmrc file to your shift repository (or your home directory):
<your-portal-host> with your Portal instance’s hostname (for example,
my-company.spotifyportal.com). The first line tells npm to route @fleetshift/*
packages to your Portal registry. Without it, npm uses the default registry and
authentication will fail.
To create your publish token:
- Generate a secure random token string (e.g.
openssl rand -base64 32). - In your Portal instance, go to App Settings (
/admin/app-settings). - Under External Access, click Add Item.
- Set type
static, subjectfleetshift-npm-registry, access restriction pluginfleetshift, and paste your generated token. - Save. Use the same token value in your
.npmrcabove.
Step 2: Publish
--registry flag is needed — the .npmrc scope line handles routing.
Publishing from CI
For automated publishing, store the service token as a CI secret. Example with GitHub Actions:Creating a shift in the wizard
- Open
Fleetshiftin your Portal sidebar. - Click
New Shiftand selectnpm Package. - Enter the package name (for example,
@fleetshift/my-shift). - Pick a version to pin. Only exact versions are accepted — no ranges like
^1.0.0or~1.0.0. - Optionally specify a custom bin name. Defaults to the unscoped package name (for
example,
my-shiftfor@fleetshift/my-shift). - Optionally add arguments to pass to the binary.
- Configure targets, PR template, and other settings as usual.
- Click
Create.
Updating a shift version
To roll out a new version of your shift logic:- Make your changes and bump the version in
package.json. - Open a PR in your shift repository and get it reviewed.
- Merge and publish the new version.
- In Fleetshift, edit the shift and update the pinned version.