ci-pipeline-synthesizer

Installation
SKILL.md

CI Pipeline Synthesizer

Generate a CI config that actually runs, by reading the repo rather than asking the user twenty questions.

Step 1 — Detect the build

Read the repo, not the user's description. Signals:

File present Ecosystem Build command Test command
package.json Node/JS npm ci then npm run build npm test
pyproject.toml / setup.py Python pip install -e . or uv sync pytest / python -m pytest
Cargo.toml Rust cargo build --release cargo test
go.mod Go go build ./... go test ./...
pom.xml Java/Maven mvn -B package mvn -B test
build.gradle / build.gradle.kts Java/Gradle ./gradlew build ./gradlew test
Makefile (and nothing else) Make make make test (if target exists)
Dockerfile (and no build system) Container-only docker build . — (look for test stage)

Read the actual file. package.json might not have a build script. Makefile might not have a test target. Adapt.

Step 2 — Choose the platform target

Signal Emit
.github/ dir exists GitHub Actions
.gitlab-ci.yml referenced in docs, or remote is gitlab.* GitLab CI
User specifies Whatever they said
No signal GitHub Actions (default — largest install base)

Step 3 — Assemble the pipeline

Every CI pipeline has the same skeleton. Fill the slots:

[trigger]          — push to main + PRs. Nothing fancier unless asked.
  [checkout]       — always
  [setup runtime]  — language-specific setup action, version pinned to whatever the repo uses
  [cache deps]     — keyed on lockfile hash
  [install deps]   — from Step 1
  [lint]           — only if a lint config exists (.eslintrc, ruff.toml, .golangci.yml)
  [build]          — from Step 1 (skip for interpreted langs with no build step)
  [test]           — from Step 1
  [security]       — optional, see below

Pin versions. actions/checkout@v4 not @main. python-version: '3.11' not '3.x'. Floating versions are reproducibility bugs waiting to happen.

Security gates

Ask or infer whether to include (opt-in — they add runtime and noise):

  • Dependency audit (npm audit, pip-audit, cargo audit) — cheap, include by default as a non-blocking step
  • SAST — only if the repo already has a config for one (.semgrep.yml, CodeQL workflow); otherwise suggest but don't inject
  • Secret scanning — usually a platform feature, not a pipeline step — mention, don't add

Worked example

Repo contents: pyproject.toml (uses hatchling), uv.lock, tests/, .github/ exists but is empty.

Output (.github/workflows/ci.yml):

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - uses: astral-sh/setup-uv@v3
      - run: uv sync --frozen
      - run: uv run pytest

Six steps. No matrix (not asked for). No coverage upload (not asked for). --frozen because uv.lock exists — fail if lockfile is stale. Python 3.12 because pyproject.toml said requires-python = ">=3.12".

Edge cases

  • Monorepo with multiple languages: Emit one job per language, with paths: filters so they only run when their subtree changes. Don't run the Python tests because someone touched the Go service.
  • No tests exist: Still emit a build-and-lint pipeline. Add a commented-out # TODO: add test step when tests exist — don't silently skip it.
  • Build needs a service (DB, Redis): Add a services: block. Detect from test fixtures or docker-compose files.
  • The repo already has a CI config: Do NOT overwrite. Read it, report what's missing, offer a diff.

Do not

  • Do not emit a 200-line pipeline for a 10-file repo. Match complexity to the project.
  • Do not add matrix builds (multiple OS/versions) unless the project is a library that claims compatibility with a range. Applications run on one thing.
  • Do not add steps for tools the repo doesn't use. No eslint step if there's no .eslintrc.
  • Do not cargo-cult continue-on-error: true. If a step can fail, decide: is it blocking or not? If not blocking, why is it there?
  • Do not inline secrets. ${{ secrets.X }} only, and list which secrets need to be configured.

Output format

## Detected
Language: <lang>  Build: <cmd>  Test: <cmd>  Platform: <ci>

## Pipeline
<file path>
<code block with full pipeline>

## Secrets to configure
- <name>: <what it's for>

## Optional next steps
- <matrix build / coverage / security gate — only what's relevant>
Related skills

More from santosomar/general-secure-coding-agent-skills

Installs
3
GitHub Stars
1
First Seen
Mar 17, 2026