agentleFS
addxaiaddxai/enterprise-harness-engineering/skills/embed-ci-setup/SKILL.md

embed-ci-setup

Skill44 starsChanged 7 months agoApache-2.0View on GitHub

Quickly create a CI Pipeline for embedded repositories (SonarQube incremental C-language scanning). Triggers when the user says "add a Pipeline to this repo", "create CI configuration", "integrate SonarQube", "embedded project needs a Pipeline", or when a repo has no .gitlab-ci.yml and cannot merge MRs.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    All embedded projects primarily using C language

    line 22
  2. Distinctive:

    All embedded repositories run CI on the company's unified GitLab platform, with these constraints:

    line 33
  3. Distinctive:

    After receiving the user's request, execute the following steps:

    line 48
  4. Very specific:

    If .gitignore does not contain /sonar-project.properties, add it.

    line 73
  5. Very specific:

    When the repository has no .gitlab-ci.yml, generate the following content:

    line 81
  6. Very specific:

    Create the ci/ directory and generate the following file:

    line 106
  7. Very specific:

    When the repository already has a .gitlab-ci.yml, add the include configuration at the top of the file.

    line 181
  8. Very specific:

    If there is already an include: section, append one entry:

    line 185
  9. Very specific:

    If there is no include: section, add at the very top of the file:

    line 194
  10. Distinctive:

    After generating files, output the following information:

    line 206

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

embed-ci-setup

Quickly create a GitLab CI Pipeline for embedded (C language) repositories with SonarQube incremental code scanning.

Description

Embedded team rule: Repositories without a Pipeline cannot merge MRs. This Skill helps embedded engineers create a standard CI Pipeline for their repository within minutes, including:

  • MR-triggered SonarQube incremental scanning (scans only .c / .h files changed in this MR)
  • Quality Gate check (shows a warning on failure, does not block the MR)
  • Dynamically generated sonar-project.properties (project key auto-generated from the repository path)

Applicable scenarios:

  • Embedded repository has no Pipeline and needs one quickly
  • Existing .gitlab-ci.yml repository needs SonarQube scanning added
  • All embedded projects primarily using C language

Not applicable:

  • Non-C language projects (Go, Python, Java, etc. should use the global SonarQube template)
  • CI workflows requiring compilation builds (this Skill only does source-code static scanning)

Rules

Rule 1 — Environment Constraints (must understand)

All embedded repositories run CI on the company's unified GitLab platform, with these constraints:

ConstraintDescription
CI entry pointManaged by your-org/ci-templates's entrypoint.yml, which auto-includes the business repository's .gitlab-ci.yml
Custom stages prohibitedDo not declare stages: in .gitlab-ci.yml; use GitLab default stages. Custom stages that do not include test will cause pipeline creation failures
include methodMust use include: project rather than include: local, because the CI entry point is in an external repository and local resolves to the wrong repository
Runner tagUse sonar-scanner
Docker imageMust specify image: harbor.example.com/tools/embed-quality:v1.2.0; runner uses Kubernetes executor
SonarQube tokenInjected via GitLab CI/CD Variable SONAR_USER_TOKEN; project admin must configure in advance
SonarQube serverhttps://sonarqube.example.com
No heredoc in YAMLDo not use <<EOF ... EOF within script: | blocks — it causes YAML parsing errors; use echo line by line instead

Rule 2 — Execution Flow

After receiving the user's request, execute the following steps:

Step 1: Check current repository status

# check if .gitlab-ci.yml exists
ls .gitlab-ci.yml 2>/dev/null

# check if ci/ directory exists
ls ci/sonar-analysis-embed.yml 2>/dev/null

# check if .gitignore has sonar-project.properties
grep "sonar-project.properties" .gitignore 2>/dev/null

Step 2: Decide action based on check results

.gitlab-ci.ymlci/sonar-analysis-embed.ymlAction
Does not existDoes not existCreate both files (Rule 3 + Rule 4)
ExistsDoes not existOnly create ci/sonar-analysis-embed.yml (Rule 4), add include to .gitlab-ci.yml (Rule 5)
ExistsExistsVerify configuration is correct; no action needed

Step 3: Update .gitignore

If .gitignore does not contain /sonar-project.properties, add it.

Step 4: Prompt user to check GitLab CI/CD Variables

Inform the user to confirm that SONAR_USER_TOKEN is configured in the project's GitLab Settings → CI/CD → Variables.

Rule 3 — Generate .gitlab-ci.yml (when no existing file)

When the repository has no .gitlab-ci.yml, generate the following content:

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_REF_NAME
    file: ci/sonar-analysis-embed.yml

default:
  tags:
    - sonar-scanner

pass:
  stage: test
  script:
    - echo "CI pass"

Key points:

  • Do not declare stages:; use GitLab defaults
  • The pass job uses stage: test to ensure the pipeline has a runnable job in non-MR scenarios
  • include uses project: $CI_PROJECT_PATH + ref: $CI_COMMIT_REF_NAME

Rule 4 — Generate ci/sonar-analysis-embed.yml

Create the ci/ directory and generate the following file:

# ============================================================================
# SonarQube Incremental Analysis Job
# Triggered on Merge Request events, scans only changed C files (.c/.h)
#
# Requires: SONAR_USER_TOKEN configured in GitLab CI/CD Variables
# ============================================================================

sonar-analysis:
  stage: test
  tags:
    - sonar-scanner
  image: harbor.example.com/tools/embed-quality:v1.2.0
  variables:
    GIT_DEPTH: "0"
    GIT_STRATEGY: fetch
    SONAR_AUTH_TOKEN: "${SONAR_USER_TOKEN}"
  before_script:
    - git config --global --add safe.directory "${CI_PROJECT_DIR}"
  script:
    - |
      echo "======================================"
      echo "SonarQube Incremental Analysis"
      echo "  Source: ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}"
      echo "  Target: ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
      echo "======================================"

      # Step 1: collect changed C files (.c/.h), exclude deleted files
      TARGET_BRANCH="origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
      SOURCE_BRANCH="origin/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}"
      CHANGED_FILES=$(git diff --name-only --diff-filter=d "${TARGET_BRANCH}...${SOURCE_BRANCH}" -- '*.c' '*.h' | paste -sd ',' -)

      if [ -z "${CHANGED_FILES}" ]; then
        echo "No C files (.c/.h) changed in this MR, skipping SonarQube analysis."
        exit 0
      fi

      echo "Changed C files:"
      echo "${CHANGED_FILES}" | tr ',' '\n' | sed 's/^/  - /'

      # Step 2: generate project key from CI_PROJECT_PATH
      # e.g. rockchip_rk3576/buildroot -> rockchip_rk3576-buildroot
      PROJECT_KEY=$(echo "${CI_PROJECT_PATH}" | tr '/' '-')
      echo "Project Key: ${PROJECT_KEY}"

      # Step 3: generate sonar-project.properties
      PROPS="${CI_PROJECT_DIR}/sonar-project.properties"
      {
        echo "sonar.projectKey=${PROJECT_KEY}"
        echo "sonar.projectName=${PROJECT_KEY}"
        echo "sonar.projectVersion=1.0"
        echo "sonar.sources=."
        echo "sonar.sourceEncoding=UTF-8"
        echo "sonar.language=c"
        echo "sonar.inclusions=${CHANGED_FILES}"
        echo "sonar.scm.provider=git"
        echo "sonar.host.url=https://sonarqube.example.com"
      } > "${PROPS}"

      echo "======================================"
      echo "Generated sonar-project.properties:"
      cat "${CI_PROJECT_DIR}/sonar-project.properties"
      echo "======================================"

      # Step 4: run sonar-scanner with quality gate check
      sonar-scanner -Dsonar.token="${SONAR_AUTH_TOKEN}" -Dsonar.qualitygate.wait=true
  allow_failure: true
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Rule 5 — Add include to existing .gitlab-ci.yml

When the repository already has a .gitlab-ci.yml, add the include configuration at the top of the file.

Check items:

  1. If there is already an include: section, append one entry:
include:
  # ... existing includes ...
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_REF_NAME
    file: ci/sonar-analysis-embed.yml
  1. If there is no include: section, add at the very top of the file:
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_REF_NAME
    file: ci/sonar-analysis-embed.yml
  1. Do not modify existing stages:, default:, other jobs, or any other configuration

Rule 6 — Notify User After Completion

After generating files, output the following information:

Files generated:
  - .gitlab-ci.yml (created / include updated)
  - ci/sonar-analysis-embed.yml
  - .gitignore (sonar-project.properties added)

Before use, please confirm:
  1. SONAR_USER_TOKEN is configured in GitLab project Settings → CI/CD → Variables
  2. Commit these files to the branch; SonarQube scan will auto-trigger when an MR is created
  3. Scan results can be viewed at https://sonarqube.example.com

Examples

Bad

User: "Add a Pipeline to this embedded repo"
AI: Declares stages: [build, test, deploy] in .gitlab-ci.yml, uses include: local to reference files,
    and uses heredoc in the script to generate sonar-project.properties
→ Pipeline creation fails: stages missing test (ci:init requires it), include: local resolves to wrong repo, heredoc causes YAML parse error
User: "This repo already has .gitlab-ci.yml, help me add SonarQube"
AI: Overwrote the user's original .gitlab-ci.yml, removing existing job configurations
→ The user's existing CI workflow is broken

Good

User: "Add a Pipeline to this embedded repo"
AI: Check finds no .gitlab-ci.yml → generates .gitlab-ci.yml (no stages declared, uses defaults)
    + ci/sonar-analysis-embed.yml (uses include: project, specifies image, echo writes properties)
    + .gitignore adds sonar-project.properties
    → Prompts user to check SONAR_USER_TOKEN configuration
User: "This repo already has .gitlab-ci.yml, help me add SonarQube"
AI: Check finds existing .gitlab-ci.yml, no ci/sonar-analysis-embed.yml
    → Only creates ci/sonar-analysis-embed.yml
    → Appends include at top of existing .gitlab-ci.yml without modifying other content
    → Prompts user to check SONAR_USER_TOKEN configuration

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.