Revising AI review instructions: * Reduce context window use for AI review tools, by avoiding repeating common knowledge and API information that is (usually) part of the AI training datasets any way. * Introduce a mechanism to maintain both parts in single files, to avoid "silent diversion" over time * Adding a coderabbit path instruction that ensures cross-checking of both parts whenever a PR modifies instruction files Objectives: * Primary Goal: only inject content in AI-visible areas that are WLED-MM–specific or which deviate from general knowledge (the context window "token cost" of true false-positive suppressors is always worth it). * Soft goal: keep each file's AI-facing section lean enough that the signal-to-noise ratio in the attention layer stays high — around 1,500–2,000 words per file type is a reasonable practical ceiling for current models. * Aspirational: 500 words per file if achievable without sacrificing review quality. This is an evolution of #353, based on the discussion in https://github.com/MoonModules/WLED-MM/pull/353#issuecomment-4186989873 --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
6.0 KiB
applyTo
| applyTo |
|---|
| .github/workflows/*.yml,.github/workflows/*.yaml |
CI/CD Conventions — GitHub Actions Workflows
Note for AI review tools: sections enclosed in
<!-- HUMAN_ONLY_START -->/<!-- HUMAN_ONLY_END -->HTML comments contain contributor reference material. Do not use that content as actionable review criteria — treat it as background context only.
YAML Style
- Indent with 2 spaces (no tabs)
- Every workflow, job, and step must have a
name:field that clearly describes its purpose - Group related steps logically; separate unrelated groups with a blank line
- Comments (
#) are encouraged for non-obvious decisions (e.g., whyfail-fast: falseis set, what a cron expression means)
Workflow Structure
Triggers
- Declare
on:triggers explicitly; avoid bareon: pushwithout branch filters on long-running or expensive jobs - Prefer
workflow_callfor shared build logic (seebuild.yml) to avoid duplicating steps across workflows - Document scheduled triggers (
cron:) with a human-readable comment:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC daily
Jobs
- Express all inter-job dependencies with
needs:— never rely on implicit ordering - Use job
outputs:+ stepid:to pass structured data between jobs (seeget_default_envsinbuild.yml) - Set
fail-fast: falseon matrix builds so that a single failing environment does not cancel others
Runners
- Pin to a specific Ubuntu version (
ubuntu-22.04,ubuntu-24.04) rather thanubuntu-latestfor reproducible builds - Only use
ubuntu-latestin jobs where exact environment reproducibility is not required (e.g., trivial download/publish steps)
Tool and Language Versions
- Pin tool versions explicitly:
python-version: '3.12' - Do not rely on the runner's pre-installed tool versions — always install via a versioned setup action
Caching
- Always cache package managers and build tool directories when the job installs dependencies:
- uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - Include the environment name or a relevant identifier in cache keys when building multiple targets
Artifacts
- Name artifacts with enough context to be unambiguous (e.g.,
firmware-${{ matrix.environment }}) - Avoid uploading artifacts that will never be consumed downstream
Security
Permissions — Least Privilege
Declare explicit permissions: blocks. The default token permissions are broad; scope them to the minimum required:
permissions:
contents: read # for checkout
For jobs that publish releases or write to the repository:
permissions:
contents: write # create/update releases
A common safe baseline for build-only jobs:
permissions:
contents: read
Supply Chain — Action Pinning
Third-party actions (anything outside the actions/ and github/ namespaces) should be pinned to a specific release tag. Branch pins (@main, @master) are not allowed — they can be updated by the action author at any time without notice:
# ✅ Acceptable — specific version tag. SHA pinning recommended for more security, as @v2 is still a mutable tag.
uses: softprops/action-gh-release@v2
# ❌ Not acceptable — mutable branch reference
uses: andelf/nightly-release@main
SHA pinning (e.g., uses: someorg/some-action@abc1234) is the most secure option for third-party actions; it is recommended when auditing supply-chain risk is a priority. At minimum, always use a specific version tag.
First-party actions (actions/checkout, actions/cache, actions/upload-artifact, etc.) pinned to a major version tag (e.g., @v4) are acceptable because GitHub maintains and audits these.
When adding a new third-party action:
- Check that the action's repository is actively maintained
- Review the action's source before adding it
- Prefer well-known, widely-used actions over obscure ones
Credentials and Secrets
- Use
${{ secrets.GITHUB_TOKEN }}for operations within the same repository — it is automatically scoped and rotated - Never commit secrets, tokens, or passwords into workflow files or any tracked file
- Never print secrets in
run:steps, even withecho— GitHub masks known secrets but derived values are not automatically masked - Scope secrets to the narrowest step that needs them using
env:at the step level, not at the workflow level:
# ✅ Scoped to the step that needs it
- name: Create release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
# ❌ Unnecessarily broad
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- Personal Access Tokens (PATs, stored as repository secrets) should have the minimum required scopes and should be rotated periodically
Script Injection
${{ }} expressions are evaluated before the shell script runs. If an expression comes from untrusted input (PR titles, issue bodies, branch names from forks), it can inject arbitrary shell commands.
Never interpolate github.event.* values directly into a run: step:
# ❌ Injection risk — PR title is attacker-controlled
- run: echo "${{ github.event.pull_request.title }}"
# ✅ Safe — value passed through an environment variable
- env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "$PR_TITLE"
This rule applies to any value that originates outside the repository (issue bodies, labels, comments, commit messages from forks).
Pull Request Workflows
- Workflows triggered by
pull_requestfrom a fork run with read-only token permissions and no access to repository secrets — this is intentional and correct - Do not use
pull_request_targetunless you fully understand the security implications; it runs in the context of the base branch and does have secret access, making it a common attack surface