CI — Pipeline Configuration Generator
Analyze a project and generate production-grade CI/CD pipeline configuration for GitHub Actions or GitLab CI. Generates separate jobs for linting, static analysis, tests, and security scanning — adapted to the project's language, framework, and existing tooling.
Three modes based on what exists:
| What exists | Mode | Action |
|---|
| No CI config | | Create pipeline from scratch with interactive setup |
| CI config exists but incomplete | | Audit & improve, add missing jobs |
| Full CI config | | Audit against best practices, fix gaps |
Step 0: Load Project Context
Read the project description if available:
Read .ai-factory/DESCRIPTION.md
Store project context for later steps. If absent, Step 2 detects everything.
Read .ai-factory/skill-context/aif-ci/SKILL.md
— MANDATORY if the file exists.
This file contains project-specific rules accumulated by
from patches,
codebase conventions, and tech-stack analysis. These rules are tailored to the current project.
How to apply skill-context rules:
- Treat them as project-level overrides for this skill's general instructions
- When a skill-context rule conflicts with a general rule written in this SKILL.md,
the skill-context rule wins (more specific context takes priority — same principle as nested CLAUDE.md files)
- When there is no conflict, apply both: general rules from SKILL.md + project rules from skill-context
- Do NOT ignore skill-context rules even if they seem to contradict this skill's defaults —
they exist because the project's experience proved the default insufficient
- CRITICAL: skill-context rules apply to ALL outputs of this skill — including generated
CI workflow files and audit reports. Templates in this skill are base structures. If a
skill-context rule says "CI MUST include step X" or "workflow MUST have job Y" — you MUST augment
the templates accordingly. Generating CI config that violates skill-context rules is a bug.
Enforcement: After generating any output artifact, verify it against all skill-context rules.
If any rule is violated — fix the output before presenting it to the user.
Step 1: Detect Existing CI & Determine Mode
1.1 Scan for Existing CI Configuration
Glob: .github/workflows/*.yml, .github/workflows/*.yaml, .gitlab-ci.yml, .circleci/config.yml, Jenkinsfile, .travis.yml, bitbucket-pipelines.yml
Classify found files:
- : contains YAML files
- : exists
- : CircleCI, Jenkins, Travis, or Bitbucket detected
1.2 Determine Mode
If contains -> set
regardless.
Path A: No CI config exists (
!HAS_GITHUB_ACTIONS && !HAS_GITLAB_CI && !HAS_OTHER_CI
):
- Set
- Proceed to Step 1.3: Interactive Setup
Path B: CI config exists but is incomplete (e.g., has only tests, no linting):
- Set
- Read all existing CI files -> store as
- Log: "Found existing CI configuration. Will analyze and add missing jobs."
Path C: Full CI setup (has linting + tests + static analysis):
- Set
- Read all existing CI files -> store as
- Log: "Found complete CI setup. Will audit against best practices and fix gaps."
1.3 Interactive Setup (Generate Mode Only)
Determine CI platform from
or ask:
If
contains
-> set
If
contains
-> set
Otherwise:
AskUserQuestion: Which CI/CD platform do you use?
Options:
1. GitHub Actions (Recommended) — .github/workflows/*.yml
2. GitLab CI — .gitlab-ci.yml
Ask about optional features:
AskUserQuestion: Which additional CI features do you need?
Options (multiSelect):
1. Security scanning — Dependency audit, SAST
2. Coverage reporting — Upload test coverage
3. Matrix builds — Test across multiple language versions
4. None — Just linting, static analysis, and tests
Store choices:
- : github | gitlab
- : boolean
- : boolean
- : boolean
1.4 Read Existing Files (Enhance / Audit Modes)
Read all existing CI files and store as
:
- All files
- Any included GitLab CI files (check directives)
Determine
from existing files.
Step 2: Deep Project Analysis
Scan the project thoroughly — every decision in the generated pipeline depends on this profile.
2.1 Language & Runtime
| File | Language |
|---|
| PHP |
| Node.js / TypeScript |
| / / | Python |
| Go |
| Rust |
| Java (Maven) |
| / | Java/Kotlin (Gradle) |
2.2 Language Version
Detect the project's language version to use in CI:
| Language | Version Source | Example |
|---|
| PHP | -> | -> |
| Node.js | -> , , | -> |
| Python | -> , | -> |
| Go | -> directive | -> |
| Rust | -> , | -> |
| Java | -> , -> | -> |
For matrix builds: use the minimum version from the project config as the lowest, and include the latest stable version. For non-matrix builds: use the latest version that satisfies the constraint.
2.3 Package Manager & Lock File
| File | Package Manager | Install Command |
|---|
| Composer | composer install --no-interaction --prefer-dist
|
| Bun | bun install --frozen-lockfile
|
| pnpm | pnpm install --frozen-lockfile
|
| Yarn | yarn install --frozen-lockfile
|
| npm | |
| uv | uv sync --all-extras --dev
|
| Poetry | |
| Pipenv | |
| pip | pip install -r requirements.txt
|
| Go modules | |
| Cargo | (built-in) |
2.4–2.7 Tool Detection
Detect project tools by scanning config files and dependencies. For the complete tool-to-command mapping → read
references/TOOL-COMMANDS.md
Categories: Linters & Formatters (PHP-CS-Fixer, ESLint, Prettier, Biome, Ruff, golangci-lint, clippy, Checkstyle), Static Analysis (PHPStan, Psalm, Rector, mypy, tsc), Test Frameworks (PHPUnit, Pest, Jest, Vitest, pytest, go test, cargo test) with coverage flags, Security Audit (composer audit, npm audit, pip-audit, govulncheck, cargo audit).
2.8 Services Detection
Check if tests require external services (database, Redis, etc.):
Grep in tests/: postgres|mysql|redis|mongo|rabbitmq|elasticsearch
Glob: docker-compose.test.yml, docker-compose.ci.yml
If services are needed, they will be configured in the CI pipeline as service containers.
2.9 Build Output
Does the project have a build step?
| Language | Has Build | Build Command |
|---|
| Node.js (with script) | Yes | / |
| Go | Yes | |
| Rust | Yes | |
| Java | Yes | mvn package -DskipTests -B
/ |
| PHP | Usually no | — |
| Python | Usually no | — |
Summary
- , , (for matrix)
- , ,
- : list of {name, command, config_file}
- : list of {name, command}
- , ,
- : list of {name, command}
- ,
- : boolean (for typecheck job)
- : list of services for CI
- : main source directory (src/, app/, lib/)
Step 3: Read Best Practices & Templates
Read skills/ci/references/BEST-PRACTICES.md
Select templates matching the platform and language:
GitHub Actions:
| Language | Template |
|---|
| PHP | |
| Node.js | templates/github/node.yml
|
| Python | templates/github/python.yml
|
| Go | |
| Rust | templates/github/rust.yml
|
| Java | templates/github/java.yml
|
GitLab CI:
| Language | Template |
|---|
| PHP | |
| Node.js | templates/gitlab/node.yml
|
| Python | templates/gitlab/python.yml
|
| Go | |
| Rust | templates/gitlab/rust.yml
|
| Java | templates/gitlab/java.yml
|
Read the selected template:
Read skills/ci/templates/<platform>/<language>.yml
Step 4: Generate Pipeline (Generate Mode)
Using the
, best practices, and template as a base, generate a customized CI pipeline.
4.1 GitHub Actions Generation
One workflow per concern — each file has its own triggers, permissions, concurrency:
| File | Name | Jobs | When to create |
|---|
| Lint | code-style, static-analysis, rector | Linters or SA detected |
| Tests | tests (+ service containers) | Always |
| Build | build | |
| Security | dependency-audit, dependency-review | |
Why one file per concern:
- Each check is a separate status check in PR — instantly see what failed
- Independent triggers — security on schedule, tests on push/PR, build only after tests
- Independent permissions — security may need
- Can disable/re-run one workflow without touching others
- Branch protection rules can require specific workflows (e.g. require but not )
When to keep single file: Only for very small projects with just lint + tests (2 jobs). As soon as there are 3+ concerns — split.
Every workflow gets the same header pattern:
yaml
name: <Name>
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
Per-file job organization:
— all code quality checks in parallel:
| Job | Purpose | When to include |
|---|
| Formatting (CS-Fixer, Prettier, Ruff format, rustfmt) | Formatter detected |
| Linting (ESLint, Ruff check, Clippy, golangci-lint) | Linter detected |
| Type checking / SA (PHPStan, Psalm, mypy, tsc) | SA tools detected |
| Rector dry-run (PHP only) | Rector detected |
All jobs run in parallel (no
). If only one tool detected (e.g. Go with just golangci-lint) — single job in the file is fine.
| Job | Purpose | When to include |
|---|
| Unit/integration tests | Always |
| Tests requiring service containers | detected |
Matrix builds (multiple language versions) only in this file.
| Job | Purpose | Notes |
|---|
| Verify compilation/bundling | Can depend on external workflow via or just run independently |
| Job | Purpose | Extra triggers |
|---|
| Vulnerability scan | schedule: cron '0 6 * * 1'
(weekly) |
| PR dependency diff | Only on |
Per-job rules:
- Each job gets its own setup (checkout, language setup, cache, dependency install)
- Use language-specific setup actions with built-in cache:
- PHP:
shivammathur/setup-php@v2
with parameter
- Node.js: with parameter
- Python: (if uv) or (if pip)
- Go: (auto-caches)
- Rust:
dtolnay/rust-toolchain@stable
+
- Java: with parameter
- Use in matrix builds
- Upload coverage as artifact when
Only the
job uses a matrix. Lint/SA jobs run on the latest version only.
yaml
tests:
name: Tests (${{ matrix.<language>-version }})
strategy:
fail-fast: false
matrix:
<language>-version: <language_versions from PROJECT_PROFILE>
Combining linter jobs:
If the project has both a formatter AND a linter from the same ecosystem, combine them into one job:
- PHP: check + other lint -> job
- Node.js: + -> job. Biome replaces BOTH ESLint and Prettier — if Biome is detected, use only in a single job
- Python: + -> job (Ruff handles both)
- Rust: + -> can be separate (fmt is fast, clippy needs compilation)
Do NOT combine lint/SA with tests — they should fail independently with clear feedback.
Use the templates in
and
as a base for generating workflow files. Follow the header pattern (name, on, concurrency, permissions) and per-file job organization described above.
4.2 GitLab CI Generation
For GitLab-specific pipeline structure, cache strategy, report format integration, and language-specific patterns → read
references/GITLAB-PATTERNS.md
Pipeline stages: install → lint → test → build → security
4.3 Service Containers
If
is not empty, add service containers to the test job.
For GitHub Actions and GitLab CI service container syntax → read
references/SERVICE-CONTAINERS.md
Quality Checks (Before Writing)
Verify generated pipeline before writing:
Correctness:
Best practices:
No over-engineering:
Step 5: Enhance / Audit Existing Pipeline
When
or
, analyze
against the project profile and best practices.
5.1 Gap Analysis
Compare existing pipeline against
:
Missing jobs:
- Linter installed but no lint job in CI?
- SA tool installed but no SA job?
- Tests exist but no test job?
- Security tools installed but no security job?
Configuration issues:
- No caching configured?
- No concurrency group (GitHub Actions)?
- Using deprecated actions (e.g., instead of )?
- Hardcoded language versions instead of variable/matrix?
- Missing on matrix?
- Using on all GitLab jobs instead of on non-install jobs?
Missing features:
- No coverage reporting when coverage tools are available?
- No JUnit/codequality report integration (GitLab)?
- No path filtering for monorepos?
- No trigger (GitHub Actions)?
5.2 Audit Report & Fix
For audit report format, fix flow options, and display templates → read
references/AUDIT-REPORT.md
Present results as tables with ✅/❌/⚠️ per check. Categorize recommendations by severity (CRITICAL, HIGH, MEDIUM, LOW). Ask user to choose: fix all, fix critical only, or show details first.
If fixing: preserve existing structure, job names, and ordering conventions.
Step 6: Write Files
6.1 Generate Mode — Write Pipeline
GitHub Actions:
Bash: mkdir -p .github/workflows
Write .github/workflows/lint.yml # If linters/SA detected
Write .github/workflows/tests.yml # Always
Write .github/workflows/build.yml # If has_build_step
Write .github/workflows/security.yml # If WANT_SECURITY
Only create files for detected concerns. If only lint + tests — two files. If the project is trivially small (single lint + single test job) — a single
is acceptable.
GitLab CI:
GitLab CI uses a single
— stages and DAG (
) handle separation.
6.2 Enhance / Audit Mode — Update Existing
Edit existing files using the
tool. Preserve the original structure and only add/modify what's needed.
Step 7: Summary & Follow-Up
7.1 Display Summary
Display summary using format from
references/AUDIT-REPORT.md
(Summary Display Template section). Show platform, files created, features, and quick start commands.
7.2 Suggest Follow-Up Skills
Suggest:
for CI targets in Makefile/Taskfile,
for containerization.
Artifact Ownership and Config Policy
- Primary ownership: CI pipeline artifacts such as and .
- Allowed companion updates: none by default outside CI files.
- Config policy: config-agnostic by design. This skill relies on repository detection and explicit user choices, not .