diff --git a/docs/guides/hosting-private-plugin.md b/docs/guides/hosting-private-plugin.md new file mode 100644 index 000000000..de933fb19 --- /dev/null +++ b/docs/guides/hosting-private-plugin.md @@ -0,0 +1,229 @@ +--- +title: Hosting and Distributing a Private Lando Plugin +description: Learn how to build, publish, and distribute a private Lando plugin using a private npm-compatible registry like GitHub Packages. + +authors: + - name: Team Lando + pic: https://gravatar.com/avatar/c335f31e62b453f747f39a84240b3bbd + link: https://twitter.com/devwithlando +updated: + timestamp: 1778457600000 + +mailchimp: + # action is required + action: https://dev.us12.list-manage.com/subscribe/post?u=59874b4d6910fa65e724a4648&id=613837077f + # everything else is optional + title: Want similar content? + byline: Signup and we will send you a weekly blog digest of similar content to keep you satiated. + button: Sign me up! +--- + +# Hosting and Distributing a Private Lando Plugin + +This guide walks through publishing a Lando plugin to a private npm-compatible registry and distributing it to developer machines — including how to handle authentication so `lando plugin-add` and automatic update checks both work seamlessly. + +[[toc]] + +## 1. Choose a Registry + +| Option | Best for | +|--------|----------| +| **GitHub Packages** | Orgs already on GitHub — free for private repos with GitHub Enterprise or limited free tier | +| **Verdaccio** | Self-hosted, lightweight, zero cost | +| **Nexus / Artifactory** | Enterprise environments with existing artifact infrastructure | + +The instructions below use GitHub Packages (`npm.pkg.github.com`) as the example, but the pattern is identical for other registries — only the registry URL and auth method differ. + +## 2. Prepare Your Plugin Package + +Your plugin needs three things to be recognized and loaded by Lando. + +### package.json + +Your `package.json` must have either a `lando` property or `"lando-plugin"` in `keywords`: + +```json +{ + "name": "@myorg/my-lando-plugin", + "version": "1.0.0", + "keywords": ["lando-plugin"], + "lando": {}, + "main": "index.js", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} +``` + +The `@myorg` scope must match your GitHub organization name when using GitHub Packages. + +### plugin.yml + +Every plugin **must** include a `plugin.yml` at its root. Lando's plugin loader filters out any plugin installed to a path matching `plugins/lando-*` unless this file exists — without it the plugin is silently ignored. + +```yaml +name: "@myorg/my-lando-plugin" + +api: 3 +is-updateable: true +``` + +### Task file + +For this demo, we're going to publish a simple command that outputs `Hello World`. Tasks live in a `tasks/` subdirectory. Each file exports a function that receives the `lando` instance: + +```javascript +// tasks/my-command.js +'use strict'; + +module.exports = lando => ({ + command: 'my-command', + describe: 'Does something useful', + usage: '$0 my-command', + level: 'tasks', + run: async () => { + console.log('Hello World'); + }, +}); +``` + +### Minimum file structure + +``` +my-lando-plugin/ +├── package.json # must have "lando": {} or lando-plugin keyword +├── plugin.yml # required — gates plugin discovery +├── index.js # minimal: module.exports = async lando => {}; +└── tasks/ + └── my-command.js +``` + +## 3. Publish the Plugin + +```bash +# Authenticate as a publisher (needs write:packages scope) +npm login --registry=https://npm.pkg.github.com --scope=@myorg + +# Publish +npm publish +``` + +For CI/CD, use a GitHub Actions token or a service account PAT: + +```bash +npm publish --registry=https://npm.pkg.github.com +``` + +## 4. Distribute Credentials to Developer Machines + +Lando reads registry credentials from `~/.lando/plugin-auth.json`. This file uses the same key format as npm's config, translated to JSON: + +```json +{ + "@myorg:registry": "https://npm.pkg.github.com", + "//npm.pkg.github.com/:_authToken": "ghp_TOKENHERE" +} +``` + +- `@myorg:registry` — tells Lando (via pacote) which registry to use for `@myorg`-scoped packages +- `//npm.pkg.github.com/:_authToken` — the auth token for that registry (nerfdart format) + +### Option A: Onboarding script (recommended) + +Write a shell script that drops the file, substituting a token from a secret manager or environment variable: + +```bash +#!/usr/bin/env bash +# onboard-lando-plugin.sh +# Requires: GITHUB_PACKAGES_TOKEN set in environment or passed as $1 + +TOKEN="${1:-$GITHUB_PACKAGES_TOKEN}" +LANDO_DIR="${HOME}/.lando" +AUTH_FILE="${LANDO_DIR}/plugin-auth.json" + +mkdir -p "$LANDO_DIR" + +cat > "$AUTH_FILE" <