{"id":51094813,"url":"https://github.com/gleanwork/pluginpack-action","last_synced_at":"2026-06-24T05:30:54.714Z","repository":{"id":364582590,"uuid":"1267872006","full_name":"gleanwork/pluginpack-action","owner":"gleanwork","description":"GitHub Action: build a pluginpack source repo and sync generated plugin output into a published repo via pull request.","archived":false,"fork":false,"pushed_at":"2026-06-13T15:10:43.000Z","size":1246,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T17:12:45.022Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gleanwork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T23:49:28.000Z","updated_at":"2026-06-13T15:10:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gleanwork/pluginpack-action","commit_stats":null,"previous_names":["gleanwork/pluginpack-action"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/gleanwork/pluginpack-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleanwork%2Fpluginpack-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleanwork%2Fpluginpack-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleanwork%2Fpluginpack-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleanwork%2Fpluginpack-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gleanwork","download_url":"https://codeload.github.com/gleanwork/pluginpack-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleanwork%2Fpluginpack-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34719083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-24T05:30:54.017Z","updated_at":"2026-06-24T05:30:54.705Z","avatar_url":"https://github.com/gleanwork.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pluginpack-action\n\nA GitHub Action that compiles a\n[pluginpack](https://github.com/gleanwork/pluginpack) source repo for a single\ntarget and reconciles the generated output against a **published** plugin repo —\nby opening a pull request, never by pushing to the output repo's default branch.\n\nIt is the publish step for a source-of-truth layout: author plugins once in a\npluginpack source repo, then sync the native output into each ecosystem's\nexisting install surface (e.g. `gleanwork/claude-plugins`,\n`gleanwork/cursor-plugins`) without moving the repos users install from.\n\n## How it works\n\n1. Check out the output repo into a temp dir (using `token`).\n2. Run `pluginpack diff --target \u003ctarget\u003e --against \u003ccheckout\u003e`.\n3. **Clean** → report up to date, exit.\n4. **Stale + `mode: check`** → fail the job. This is the guard an output repo\n   runs to keep hand-edits from drifting away from source.\n5. **Stale + `mode: sync`** → `pluginpack build --out-dir \u003ccheckout\u003e`, commit to\n   a machine-owned branch `pluginpack/sync-\u003ctarget\u003e`, force-push that branch,\n   and open or update a PR into `output-ref`.\n\nThe sync branch is force-updated on every run (idempotent). The action never\ncommits to the output repo's base branch — a human (or a separately configured\nauto-merge) merges the PR.\n\n## Usage\n\n```yaml\n# In the source repo (e.g. agent-plugins), on release:\njobs:\n  sync-claude:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n    concurrency:\n      group: pluginpack-sync-claude\n      cancel-in-progress: true\n    steps:\n      # Mint a short-lived token scoped only to the output repo.\n      - uses: actions/create-github-app-token@v3\n        id: app-token\n        with:\n          client-id: ${{ secrets.PLUGINPACK_CLIENT_ID }}\n          private-key: ${{ secrets.PLUGINPACK_APP_KEY }}\n          owner: gleanwork\n          repositories: claude-plugins\n      - uses: actions/checkout@v5\n      - uses: actions/setup-node@v5\n        with:\n          node-version: 24\n      - uses: gleanwork/pluginpack-action@v1\n        with:\n          target: claude\n          output-repo: gleanwork/claude-plugins\n          token: ${{ steps.app-token.outputs.token }}\n```\n\n## Authentication\n\nThe action needs a token with **`contents: write`** and\n**`pull_requests: write`** on each output repo — to push the machine-owned sync\nbranch and open the PR. It never needs write access to the source repo. Provide\nit one of two ways.\n\n### GitHub App (recommended)\n\nShort-lived, least-privilege, and not tied to a person.\n\n1. Create a GitHub App in the org (**Settings → Developer settings → GitHub Apps\n   → New**). Under **Repository permissions** grant **Contents: Read and write**\n   and **Pull requests: Read and write**. No webhook needed.\n2. **Install** the App on the output repos (e.g. `claude-plugins`,\n   `cursor-plugins`).\n3. In the **source** repo (where this action runs) add two Actions **secrets**:\n   - `PLUGINPACK_CLIENT_ID` — the App's **Client ID** (on the App's General\n     page, e.g. `Iv23li…`). `create-github-app-token` v3 uses `client-id`; the\n     numeric App ID is deprecated.\n   - `PLUGINPACK_APP_KEY` — a generated private key (the full `.pem` contents).\n4. Mint a per-run token with `actions/create-github-app-token`, scoped to just\n   the target output repo, and pass it to `token` (see [Usage](#usage)).\n\nThe Client ID isn't sensitive, so a repo **variable** works for it too; we keep\nboth as secrets so all App credentials live in one place. The names are\narbitrary — match them to whatever your `create-github-app-token` step\nreferences.\n\n### Personal access token (simpler)\n\nA fine-grained **PAT** with **Contents: Read and write** and **Pull requests:\nRead and write** on the output repos, stored as a secret. Drop the app-token\nstep and pass the secret straight through:\n\n```yaml\nsteps:\n  - uses: actions/checkout@v5\n  - uses: actions/setup-node@v5\n    with:\n      node-version-file: .node-version\n  - uses: gleanwork/pluginpack-action@v1\n    with:\n      target: claude\n      output-repo: gleanwork/claude-plugins\n      token: ${{ secrets.PLUGINPACK_SYNC_TOKEN }}\n```\n\nA PAT is tied to its creator and longer-lived than an App token — rotate it\nperiodically.\n\n## Inputs\n\n| Input                | Required | Default           | Description                                                             |\n| -------------------- | -------- | ----------------- | ----------------------------------------------------------------------- |\n| `target`             | yes      | —                 | pluginpack target to build (`claude`, `cursor`, …).                     |\n| `output-repo`        | yes      | —                 | Published repo to sync into, as `owner/name`.                           |\n| `output-ref`         | no       | `main`            | Base branch the sync PR targets.                                        |\n| `token`              | yes      | —                 | Token with `contents:write` + `pull-requests:write` on the output repo. |\n| `mode`               | no       | `sync`            | `sync` opens/updates a PR when stale; `check` fails when stale.         |\n| `pluginpack-version` | no       | `latest`          | npm version/dist-tag of `@gleanwork/pluginpack`.                        |\n| `working-directory`  | no       | `.`               | Path to the checked-out pluginpack source repo.                         |\n| `pr-branch-prefix`   | no       | `pluginpack/sync` | Prefix for the sync branch; `-\u003ctarget\u003e` is appended.                    |\n| `pr-labels`          | no       | `pluginpack-sync` | Comma-separated labels for the sync PR.                                 |\n\n## Outputs\n\n| Output      | Description                                                |\n| ----------- | ---------------------------------------------------------- |\n| `stale`     | `\"true\"` when the output repo differed from a fresh build. |\n| `pr-number` | Number of the opened/updated sync PR (sync mode).          |\n| `pr-url`    | HTML URL of the sync PR (sync mode).                       |\n\n## Development\n\nThis action follows the\n[`actions/typescript-action`](https://github.com/actions/typescript-action)\nconventions: TypeScript in `src/`, bundled to `dist/` with Rollup, tested with\nVitest. Run `npm run all` (format, lint, test, package) before committing; the\ncommitted `dist/` is what runs, so `check-dist.yml` enforces it stays current.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgleanwork%2Fpluginpack-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgleanwork%2Fpluginpack-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgleanwork%2Fpluginpack-action/lists"}