CI/CD setup
Pin LPM CLI, authenticate, install from a committed lockfile, and run project checks in CI.
Use lpm ci to install a committed dependency graph. Keep authentication, package checks, and publication as explicit steps.
npm install --global @lpm-registry/cli@0.78.0
lpm ci --strict-integrity
lpm run build
lpm run testThe examples pin LPM CLI to 0.78.0. Update that version through your normal review process. The build and test commands require matching package scripts.
Commit project configuration
Commit package.json and lpm.lock. If lpm.json is present, commit it.
Also commit the other LPM project files that the project uses, such as patches/, lpm-sources.json, lpm-agent-skills.json, and lpm-changes/. .lpm/ holds local state and keeps itself out of Git. See Files LPM CLI creates.
lpm.lock records the overrides and patches its resolution used, so a fresh CI checkout installs from the lockfile without state from an earlier install.
Use lpm.json for shared runtime versions, tasks, and publication targets. Registry credentials belong in the CI secret store.
{
"tasks": {
"build": {
"command": "tsc",
"inputs": ["src/**", "tsconfig.json", "package.json"],
"outputs": ["dist/**"],
"cache": true
}
}
}Install TypeScript as a project dependency for this example. Adapt the input and output lists to your build.
GitHub Actions
name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install --global @lpm-registry/cli@0.78.0
- uses: actions/cache@v4
with:
path: ~/.lpm/store
key: lpm-store-${{ runner.os }}-${{ runner.arch }}-0.78.0-${{ hashFiles('lpm.lock') }}
- run: lpm ci --strict-integrity
- run: lpm run build
- run: lpm run testThis example uses public dependencies. Add credentials only to jobs that need protected packages. Pin action revisions and the runtime to your team's approved versions.
A cache miss is valid: the online frozen install downloads the locked packages. --offline is unnecessary for lockfile freezing.
Authenticate protected dependencies
LPM CLI supports public npm, private registries through .npmrc, and LPM.dev Registry. An LPM.dev Registry account is unnecessary for public npm.
For LPM.dev Registry, store a read-scoped token in the CI secret store:
- run: lpm ci --strict-integrity
env:
LPM_TOKEN: ${{ secrets.LPM_TOKEN }}For npm-compatible private registries, provide endpoint-scoped credentials through .npmrc. See authentication for supported credential sources.
Use OIDC in the supported workflows
Registry OIDC supports publication, hosted Firewall checks, and credential setup for other npm-compatible clients.
It does not provide general OIDC authentication for lpm ci downloads of protected @lpm.dev/* packages. Use LPM_TOKEN for that workflow.
For an npm-compatible client that needs temporary Registry credentials:
lpm setup ci npmrc --oidclpm setup ci npmrc writes an owner-only .npmrc where installs read it: the workspace root, or else the nearest directory with a package.json. It refuses an .npmrc that Git tracks and adds the file to .git/info/exclude, which keeps it out of commits without changing a tracked file. The receiving client uses that file and its own supported install workflow.
Exclude the credential file from artifacts and caches. Writing it does not authenticate LPM CLI's direct Registry downloads.
GitHub Actions needs permissions: id-token: write on the trusted job. GitLab supplies LPM_OIDC_TOKEN with audience https://lpm.dev.
Pull-request triggers do not qualify for this Registry exchange. Configure the required trust before the job runs.
A supplied assertion cannot be reused after exchange. Obtain a fresh assertion for each independent exchange.
Understand frozen and offline installation
lpm ci --strict-integrity --no-skills --no-security-summary| Option | Effect |
|---|---|
lpm ci | Requires a current, replayable lockfile. |
--strict-integrity | Requires inline integrity for tarball-URL dependencies instead of first-use trust. |
--offline | Uses available local package data and fails when required data is missing, or when the overrides differ from the ones lpm.lock was resolved with. |
--no-skills | Skips package skills and the restore of recorded agent skills. Without it, unavailable skills produce warnings and never fail the install. |
--no-security-summary | Skips the post-install report. Separate audit commands still work. |
For an intentionally prepared offline job:
lpm fetch
lpm ci --offline --strict-integrityKeep the populated store available to both commands. Local file: and link: dependencies also need their source directories.
Offline is not a network sandbox. Root lifecycle scripts still run and can access the network. Use a network-restricted runner for an actual egress boundary.
Dependency lifecycle scripts remain subject to script approval. Review required trust entries before committing them.
Run project and policy checks
For existing project scripts:
lpm run build
lpm run test
lpm run lintExplicit lpm run preserves your scripts and arguments. lpm test and lpm lint can select their own supported runners.
Add the security and license gates that match your policy:
lpm audit --fail-on vuln
lpm licenses --fail-on copyleft,missing
lpm licenses --deny GPL-3.0 --deny AGPL-3.0These commands return nonzero when their configured gate fails. See exit codes.
lpm trust diff compares the manifest with a local install snapshot. A successful install refreshes that snapshot.
A diff after lpm ci therefore does not detect changes against an approved Git revision. Review trust changes against your trusted repository baseline.
Enforce npm Firewall checks
- run: LPM_NPM_FIREWALL=enforce lpm ci --strict-integrity
env:
LPM_TOKEN: ${{ secrets.LPM_TOKEN }}Hosted checks need eligible account coverage and network access. Enforce mode stops when the check is unavailable. Monitor mode warns and continues.
See Firewall for npm for scope, policy groups, and offline limitations.
Cache reusable data
| Path | Use |
|---|---|
~/.lpm/store | Downloaded package data for installation. |
~/.lpm/plugins | Managed tool binaries. Include platform and tool configuration in the cache key. |
~/.lpm/cache/dlx | Optional cache for temporary package commands. |
These paths are under the LPM home. If the job sets LPM_HOME, cache the same subdirectories under $LPM_HOME instead.
Cache these directories separately from credentials. Do not cache the entire LPM home, which also holds login state and local env secrets, or project secret storage.
Regenerate node_modules from the lockfile and store. A restored store can still require downloads for another platform or missing package.
For shared task outputs, configure remote cache. Keep task inputs and outputs accurate before enabling cache reuse.
Publish from a trusted release job
For npm, configure Trusted Publishing, or supply NPM_TOKEN only to the publish step:
- run: lpm publish --npm --check --json
- run: lpm publish --npm --ignore-scripts --yes --json
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}npm Trusted Publishing uses GitHub Actions runtime identity or NPM_ID_TOKEN with audience npm:registry.npmjs.org. An available npm token can provide fallback authentication.
Build the package before these steps. If the release job intentionally authorizes publish lifecycle scripts, remove --ignore-scripts.
For LPM.dev Registry, configure a Trusted Publisher on an existing package. GitHub Actions needs id-token: write and a matching trusted release identity.
lpm publish --lpm --check --json
lpm publish --lpm --ignore-scripts --yes --wait --jsonRegistry OIDC authentication and Sigstore provenance use different audiences. See publishing a package for provenance and GitLab examples.
If a post-publish hook or availability wait fails, check the registry before retrying. The version can already be uploaded.
Troubleshooting
| Failure | Recovery |
|---|---|
| Missing or stale lockfile | Run an online lpm install locally and review the updated lockfile. |
| Offline install reports changed overrides | Run an online lpm install locally, commit lpm.lock, then retry. |
| Offline package missing | Populate the matching store online before the offline step. |
| OIDC exchange rejected | Check the trigger, trust configuration, audience, and assertion reuse. |
| Build tool missing | Declare it as a project dependency and use the intended runtime. |
| Workspace selection is wrong | Preview it with lpm filter. |
See also
- lpm setup — CI credentials and workflow setup
- Publishing a package — release workflow
- Managing secrets — application variables
- Docker deployments — container builds