From 9aa111f5e2e202bde998a4d4479ac8443c5b4eea Mon Sep 17 00:00:00 2001 From: Den Delimarsky Date: Tue, 10 Mar 2026 16:40:37 +0000 Subject: [PATCH] Convert README actions list to table, add CLAUDE.md - README.md: list actions in a table with separate rows for deploy/cleanup - CLAUDE.md: conventions for adding new composite actions (layout, shell requirement, env-var input passing, secrets, github-token, README requirements, validation) --- CLAUDE.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 ++- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9796cf1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,135 @@ +# Adding new actions to this repo + +This repo holds **composite GitHub Actions** reused across MCP-family repos. +Before adding a new action, confirm the logic is (or will be) needed in more +than one caller repo — single-repo logic should stay in that repo's workflow. + +## Directory layout + +Each action lives in its own directory. If a feature has multiple related +entry points (e.g. deploy + cleanup), group them under a common parent: + +``` +/ + README.md # usage docs, inputs/outputs, caller requirements + action.yml # the composite action +``` + +or for multi-action groups: + +``` +/ + README.md # covers all actions in the group + / + action.yml + / + action.yml +``` + +Caller references: +- `modelcontextprotocol/actions/@main` +- `modelcontextprotocol/actions//@main` + +## Composite action conventions + +**Required fields** + +Every `action.yml` must include: +- `name` — human-readable name +- `description` — one or two sentences on what it does +- `inputs` — with `description` and `required` for each; use `default` for + optional inputs +- `runs.using: composite` + +**Every `run:` step needs an explicit `shell:`** + +Composite actions do not inherit a default shell. Omitting `shell:` fails at +runtime, not validation time. + +```yaml +- name: Do something + shell: bash + run: | + echo "..." +``` + +**Pass inputs to scripts via `env:`, not interpolation** + +Direct interpolation of `${{ inputs.* }}` into `run:` or `script:` bodies is +an injection vector. Pass values through `env:` and read them as environment +variables or `process.env.*`: + +```yaml +- shell: bash + env: + MY_INPUT: ${{ inputs.my-input }} + run: | + echo "${MY_INPUT}" + +- uses: actions/github-script@v8 + env: + MY_INPUT: ${{ inputs.my-input }} + with: + script: | + const val = process.env.MY_INPUT; +``` + +**Do not `actions/checkout` inside a composite action** + +The caller has already checked out; the composite runs in that workspace. +Document in the README if a checkout is required on the caller side. + +**Secrets are always caller-provided** + +Composite actions cannot access `secrets.*` directly. Define inputs for any +credentials and document in the README which secrets the caller must configure +and pass through. + +**`github-token` input** + +If the action posts comments, creates issues, or otherwise calls the GitHub +API, accept a `github-token` input with default `${{ github.token }}`. This +lets callers override with a PAT if needed: + +```yaml +github-token: + description: GitHub token for API calls + required: false + default: ${{ github.token }} +``` + +**Outputs** + +Expose anything a caller might want to reference downstream. Wire outputs from +steps to the action's `outputs:` block: + +```yaml +outputs: + url: + description: Deployment URL + value: ${{ steps.deploy.outputs.url }} +``` + +## README requirements + +Each action (or group) must have a `README.md` covering: + +1. **What it does** — one paragraph per action +2. **Prerequisites** — external resources that must exist (CF project, etc.) +3. **Caller requirements** — `permissions:`, fork-PR guards, concurrency, + required secrets +4. **Usage** — a minimal but complete caller workflow example +5. **Inputs/outputs** — tables with name, required, default, description + +## Registering the action + +Add a row to the root [`README.md`](README.md) table with the action path and +a one-line description. + +## Validation + +- Parse check: `python3 -c "import yaml; yaml.safe_load(open('path/action.yml'))"` +- Structure: verify every `run:` step has `shell:` +- Full verification requires a live caller workflow — open a PR in a consuming + repo that references `@` and confirm end-to-end behavior before + merging diff --git a/README.md b/README.md index 7b981f9..9021ff8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # actions + GitHub Actions relevant to the management of MCP repositories. ## Actions -- [`cloudflare-pages-preview`](cloudflare-pages-preview/README.md) — deploy PR previews to Cloudflare Pages and clean them up on close +| Action | Description | +|---|---| +| [`cloudflare-pages-preview/deploy`](cloudflare-pages-preview/README.md) | Deploy a static HTML directory to Cloudflare Pages under a per-PR branch alias, inject noindex headers, and post a sticky PR comment with preview URLs | +| [`cloudflare-pages-preview/cleanup`](cloudflare-pages-preview/README.md) | Delete Cloudflare Pages deployments for a closed PR's branch alias and update the sticky comment |