一键导入
ci-workflows
How to read, write, and extend GitHub Actions workflows in OpenCookbook. Covers the existing deploy-pages workflow, conventions for new workflows, and patterns for dotnet builds, PR checks, and preview deployments.
菜单
How to read, write, and extend GitHub Actions workflows in OpenCookbook. Covers the existing deploy-pages workflow, conventions for new workflows, and patterns for dotnet builds, PR checks, and preview deployments.
How to format and structure a recipe YAML file in the OpenCookbook repository. Use this skill when writing, editing, or reviewing any recipe file. Covers every field, unit rule, and file convention.
Autonomous execution protocol for implementing tasks. Governs planning, iteration, subagent use, verification, and self-correction. Use when executing any non-trivial implementation work — recipe edits, code changes, CI/CD updates, or multi-step tasks.
End-of-session self-evaluation for continuous improvement. Run before finalizing any session to capture lessons learned, identify skill updates, and improve agent effectiveness. Use when completing a task, reviewing work quality, or improving project skills.
Checklist for validating an OpenCookbook recipe. Use when reviewing a recipe before promotion, after edits, or for quality checking. Fix everything you can. Only flag issues that need the author's judgment.
Data model and layout specification for rendering OpenCookbook recipes on a webpage or as a PDF. Defines how YAML recipe data maps to visual output. Language-agnostic - covers data structure and layout intent, not implementation.
How to fill in the PULL_REQUEST_TEMPLATE.md when creating or updating a PR in OpenCookbook. Covers the PR Title Check, description, type of change, checklist generation, and related issues.
| name | ci-workflows |
| description | How to read, write, and extend GitHub Actions workflows in OpenCookbook. Covers the existing deploy-pages workflow, conventions for new workflows, and patterns for dotnet builds, PR checks, and preview deployments. |
| license | CC0-1.0 |
| metadata | {"author":"JPEGtheDev","version":"1.1"} |
Use this when:
| File | Trigger | Purpose |
|---|---|---|
.github/workflows/deploy-pages.yml | Push to main, workflow_dispatch | Build Blazor WASM, generate recipe index, deploy to GitHub Pages |
.github/workflows/pr-build.yml | pull_request targeting main | Build/test, upload artifact, post download instructions comment on PR |
.github/workflows/pr-preview.yml | pull_request_target closed targeting main | Update PR comment when PR is closed/merged |
OpenCookbook/
├── Recipes/ # YAML recipe files — copied to WASM output at build time
├── visualizer/ # Blazor WASM project root
│ ├── src/
│ │ └── OpenCookbook.Web/
│ │ └── OpenCookbook.Web.csproj
│ └── (test projects)
└── .github/
└── workflows/
All dotnet commands must use working-directory: visualizer.
Both deploy-pages.yml and pr-build.yml call these scripts instead of duplicating inline shell:
| Script | Purpose |
|---|---|
scripts/copy-recipes.sh <output_dir> | Copies Recipes/**/*.yaml into <output_dir>/recipes/ preserving folder structure |
scripts/generate-recipe-index.py <recipes_dir> | Generates recipe-index.json from YAML metadata (name, path, status, description) |
scripts/generate-recipe-pages.py <recipes_dir> <output_dir> <base_url> | Generates a static canonical page per recipe at recipe/{slug}/index.html by injecting Schema.org JSON-LD into a copy of the Blazor index.html so crawlers see JSON-LD at a 200 OK URL |
scripts/prepare-spa.sh <output_dir> | Adds .nojekyll and copies index.html → 404.html for SPA routing |
scripts/serve.py [port] | Bundled in artifact. Python SPA server for local preview (handles .wasm MIME type, falls back unknown paths to index.html) |
All scripts use set -euo pipefail. Never add inline versions of these steps — call the scripts.
deploy-pages.ymldotnet restore — restores NuGet packagesdotnet test — runs all tests (no-restore, normal verbosity)dotnet publish — publishes the Blazor WASM app to visualizer/output/Recipes/**/*.yaml files into visualizer/output/wwwroot/recipes/, preserving folder structurerecipe-index.json from the copied YAML files (name, path, status, description).nojekyll and copies index.html → 404.html for SPA routingvisualizer/output/wwwroot as a Pages artifactactions/deploy-pages@v4permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
cancel-in-progress: false ensures a deploy already in progress is not cancelled. Use this on all deploy workflows.
kebab-case.yml (e.g. pr-build.yml, pr-preview.yml)name: field: human-readable sentence case (e.g. Build PR, Deploy PR Preview)build, test, deploy, cleanup — lowercase, single word where possibleAlways use main (the repo's default branch).
All changes go through branches and pull requests — never push directly to main.
on:
push:
branches: [main]
pull_request:
branches: [main]
Always pin to 10.0.x:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
All dotnet commands run from the visualizer/ subdirectory:
- name: Restore
working-directory: visualizer
run: dotnet restore
| Action | Version |
|---|---|
actions/checkout | @v4 |
actions/setup-dotnet | @v4 |
actions/upload-pages-artifact | @v3 |
actions/deploy-pages | @v4 |
actions/upload-artifact | @v4 |
actions/download-artifact | @v4 |
actions/github-script | @v7 |
Do not use @latest or unpinned versions.
Only declare permissions your workflow actually needs. Start from this minimum and add only what is required:
permissions:
contents: read
Common additions:
pull-requests: write — to post comments on PRspages: write + id-token: write — to deploy to GitHub Pagesdeployments: write — to create deployment environmentsAll workflows that deploy or post comments must have a concurrency group to prevent races:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # ok for build/test jobs
For deploy jobs, use cancel-in-progress: false.
pr-build.yml — dotnet build check on every PR ✅ ImplementedSee .github/workflows/pr-build.yml. Triggers on pull_request targeting main. Runs full build/test pipeline, uploads the built site as an artifact, and posts a PR comment with download instructions.
Artifact-based PR preview approach: The built site (including scripts/serve.py) is uploaded as a GitHub Actions artifact named pr-preview-site. The PR comment posts a gh CLI command (including -D pr-preview-site so the artifact extracts into a known folder) and a curl one-liner so reviewers can download and serve the site locally with python3 serve.py from the extracted directory. This avoids overwriting the production GitHub Pages site.
Key points:
contents: read + pull-requests: write only. No pages: write or id-token: write needed.upload-artifact step outputs artifact-id — capture this with id: upload and pass it to the comment script via env:.serve.py handles .wasm MIME type and SPA route fallback. It is copied into the artifact output dir before upload so it travels with the build.Version is embedded in the .csproj or via a Directory.Build.props file. The CI workflow reads the version and can tag builds. No separate workflow file needed — this is a project-level change.
fix(website): stale site on returning visitsImplemented in the Blazor project itself (service worker update strategy or cache headers), not in the workflow. No new workflow file needed unless the fix requires a build-time step.
pr-preview.yml — PR preview cleanup ✅ ImplementedSee .github/workflows/pr-preview.yml. Uses pull_request_target (types: closed) so it fires when a PR is merged or closed. Updates the ## 📦 PR Preview Built bot comment to indicate the artifact is no longer available.
Note: Uses pull_request_target not pull_request — this is required to get write permissions on the GITHUB_TOKEN when the PR is from a fork. The job only makes GitHub API calls, no code checkout.
| Purpose | Command |
|---|---|
| Restore packages | dotnet restore |
| Build (no restore) | dotnet build --no-restore |
| Run tests | dotnet test --no-restore --verbosity normal |
| Publish release | dotnet publish <project>.csproj -c Release -o <output-dir> |
Always pass --no-restore to build/test/publish when a prior restore step exists in the same job.
| Symptom | Likely cause |
|---|---|
| Workflow never triggers on push | Branch name mismatch — check branches: trigger matches main |
dotnet command not found | Missing setup-dotnet step |
working-directory error | Path is wrong — must be visualizer, not visualizer/src |
| Pages deploy fails with permission error | Missing pages: write or id-token: write permission |
| Recipe index missing entries | YAML copy step ran before dotnet publish created output dir |
| PR comment not posted | Missing pull-requests: write permission |