一键导入
add-recipe
Create a new recipe test harness that verifies an external recipe repository. Use when adding a new recipe to the cookbook.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create a new recipe test harness that verifies an external recipe repository. Use when adding a new recipe to the cookbook.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | add-recipe |
| description | Create a new recipe test harness that verifies an external recipe repository. Use when adding a new recipe to the cookbook. |
| argument-hint | [recipe-name] |
Create a test harness under recipes/{pathway}/{recipe-name}/ that clones an external repo, builds it, and runs its tests.
Recipe source code lives in external repos (e.g., brunopgalvao/recipe-{name}). This repo only contains the test harness.
Create these files in recipes/{pathway}/{recipe-name}/:
package.json:
{
"name": "{recipe-name}-test",
"version": "1.0.0",
"description": "Verification tests for the {recipe-name} recipe",
"type": "module",
"scripts": {
"test": "vitest run"
},
"devDependencies": {
"@types/node": "^22.10.5",
"typescript": "^5.7.2",
"vitest": "^2.1.9"
}
}
tsconfig.json:
{
"extends": "../../../shared/tsconfig.base.json",
"include": ["tests/**/*.ts"]
}
vitest.config.ts:
import { defineConfig } from "vitest/config";
import { sharedVitestConfig } from "../../../shared/vitest.shared";
export default defineConfig({
test: {
...sharedVitestConfig,
testTimeout: 300000, // 5 min for Node.js recipes, 2700000 (45 min) for Rust
hookTimeout: 60000,
include: ["tests/recipe.test.ts"],
},
});
.gitignore:
recipe-{name}/
README.md:
# {Recipe Title}
[](https://github.com/polkadot-developers/polkadot-cookbook/actions/workflows/recipe-{recipe-name}.yml)
[{Recipe Title}](https://github.com/brunopgalvao/recipe-{recipe-name})
## Running Tests
\```bash
npm ci
npm test
\```
Create tests/recipe.test.ts with this lifecycle:
import { describe, it, expect } from "vitest";
import { execSync } from "child_process";
import { existsSync } from "fs";
import { join } from "path";
const REPO_URL = "https://github.com/brunopgalvao/recipe-{recipe-name}";
const REPO_VERSION = "v1.0.0"; // Must be a git tag
const CLONE_DIR = join(process.cwd(), "recipe-{recipe-name}");
describe("{Recipe Title}", () => {
describe("1. Prerequisites", () => {
it("should have required tools", () => {
// Check node/npm, git, cargo, etc.
execSync("node --version", { encoding: "utf-8" });
execSync("git --version", { encoding: "utf-8" });
});
});
describe("2. Clone Repository", () => {
it("should clone at pinned version", () => {
if (!existsSync(CLONE_DIR)) {
execSync(`git clone --branch ${REPO_VERSION} --depth 1 ${REPO_URL} ${CLONE_DIR}`, {
encoding: "utf-8",
stdio: "inherit",
});
}
expect(existsSync(join(CLONE_DIR, "package.json"))).toBe(true);
}, 120000);
});
describe("3. Install Dependencies", () => {
it("should install", () => {
execSync("npm ci", { cwd: CLONE_DIR, encoding: "utf-8", stdio: "inherit" });
});
});
describe("4. Build", () => {
it("should compile", () => {
// e.g., execSync("npx hardhat compile", { cwd: CLONE_DIR, ... });
});
});
describe("5. Test", () => {
it("should pass tests", () => {
// e.g., execSync("npx hardhat test", { cwd: CLONE_DIR, ... });
});
});
});
Pinning strategy: Recipe tests pin external repos by git tag (e.g., v1.0.0).
Timeouts: Node.js recipes ~5 min, Rust recipes ~45 min.
Create .github/workflows/recipe-{recipe-name}.yml:
name: {Readable Recipe Name}
on:
push:
branches: [master]
paths:
- 'recipes/{pathway}/{recipe-name}/**'
pull_request:
paths:
- 'recipes/{pathway}/{recipe-name}/**'
workflow_dispatch:
jobs:
test:
if: github.repository == 'polkadot-developers/polkadot-cookbook'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install npm dependencies
run: |
cd recipes/{pathway}/{recipe-name}
npm ci
- name: Run tests
run: |
cd recipes/{pathway}/{recipe-name}
npm test
timeout-minutes: 15
Add versions.yml to path triggers if the recipe depends on pinned versions.
CI setup for smart contract recipes:
setup-revive-dev-node action — runs a vanilla pallet-revive dev node + eth-rpc adaptersetup-zombienet-eth-rpc action — requires a full network with a custom runtime that includes the precompileFor Rust recipes, add Rust toolchain setup and cargo caching.
cd recipes/{pathway}/{recipe-name}
npm install # generates package-lock.json (commit this)
npm test
Place the recipe in the correct pathway directory:
recipes/pallets/ — FRAME pallet development (Rust)recipes/contracts/ — Solidity smart contracts (Hardhat)recipes/transactions/ — Chain interactions (PAPI, TypeScript)recipes/cross-chain-transactions/ — XCM messaging (Chopsticks)recipes/networks/ — Network testing (Zombienet, Chopsticks)Regenerate all brand assets under .github/media/ from .github/brand/tokens.yml. Run after editing tokens, templates, or bumping the workspace version.
Cut a new versioned release. Analyzes changes since last tag, determines semver bump, generates release notes and manifest, updates Cargo.toml and CHANGELOG.md, and opens a draft PR that triggers publish-release.yml on merge. Supports `--dry-run` to preview all artifacts in a scratch dir without any git or GitHub mutations.
Automated pipeline to create a polkadot-docs test harness from a tutorial URL. Analyzes the guide, generates all files, runs tests, debugs failures, and creates PRs.
Detect upstream changes to polkadot-docs tutorials, classify drifts, and sync dependency versions from upstream variables.yml.
Verify that internal documentation (READMEs, docs/ site, badges) stays consistent with the codebase. Catches version mismatches, broken links, and stale references.