Claude Code Plugins

Community-maintained marketplace

Feedback

building-gitlab-ci-components

@nagyv/claude-commands
6
0

Use when creating reusable GitLab CI/CD configurations, building component catalog entries, or packaging pipeline templates for sharing - provides systematic guide following GitLab documentation to avoid missing required files, directory structure, input specifications, or testing/publishing configuration

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name building-gitlab-ci-components
description Use when creating reusable GitLab CI/CD configurations, building component catalog entries, or packaging pipeline templates for sharing - provides systematic guide following GitLab documentation to avoid missing required files, directory structure, input specifications, or testing/publishing configuration

Building GitLab CI Components

Overview

GitLab CI components are reusable pipeline configuration units that can be versioned, shared, and discovered through the CI/CD Catalog. This skill guides you through creating complete, correct components following GitLab's official structure.

Core principle: Follow the GitLab documentation systematically. Components have specific requirements for directory structure, files, inputs, and CI/CD configuration that must be met for valid components.

When to Use

Use this skill when:

  • Creating a new reusable CI/CD component
  • Packaging existing pipeline configuration for sharing
  • Publishing components to the GitLab CI/CD Catalog
  • Setting up a component project structure

Critical Requirements Checklist

These are commonly missed - verify each one:

  • Directory structure: templates/ directory with components as .yml files or subdirectories with template.yml
  • Required files: README.md, LICENSE.md, .gitlab-ci.yml present
  • Testing configuration: .gitlab-ci.yml includes jobs to test component behavior
  • Publishing configuration: .gitlab-ci.yml includes release job for catalog publishing
  • Input specification: spec:inputs syntax correct with proper types and validation
  • Input usage: Inputs referenced as $[[ inputs.field-name ]] in template
  • YAML separator: --- separator present between spec and job definitions
  • No hardcoded values: Use $CI_SERVER_FQDN and inputs instead of hardcoded domains/values

Directory Structure

Single Component Project

my-component/
├── templates/
│   └── my-component.yml      # Component definition
├── README.md                  # Documentation with usage examples
├── LICENSE.md                 # Required license file
└── .gitlab-ci.yml            # Testing and publishing

Multi-Component Project

my-components/
├── templates/
│   ├── component-one.yml                    # Simple single-file component
│   ├── component-two/                       # Multi-file component
│   │   ├── template.yml                     # Main template
│   │   └── supporting-script.sh             # Supporting files
│   └── component-three.yml
├── README.md                                 # Covers all components
├── LICENSE.md
└── .gitlab-ci.yml

Limits:

  • Maximum 100 components per project (GitLab 18.5+)
  • Earlier versions: 30 components maximum

Component Template Structure

Basic Template with Inputs

spec:
  inputs:
    stage:
      type: string
      default: test
      description: "Pipeline stage for the job"

    dockerfile_path:
      type: string
      default: Dockerfile
      description: "Path to Dockerfile"

    image_name:
      type: string
      description: "Docker image name (required)"

    image_tag:
      type: string
      default: latest
      description: "Docker image tag"
---
build-docker-image:
  stage: $[[ inputs.stage ]]
  image: docker:latest
  script:
    - docker build -f $[[ inputs.dockerfile_path ]] -t $[[ inputs.image_name ]]:$[[ inputs.image_tag ]] .

Key syntax:

  • spec:inputs: defines configurable parameters
  • --- separator required between spec and jobs
  • $[[ inputs.field-name ]] for referencing inputs
  • Inputs without default are required

Input Specification

Input attributes:

  • type: Data type (string, number, boolean, array)
  • default: Default value (makes input optional)
  • description: Documents the input purpose

Validation options:

  • type: Enforces data type
  • regex: Pattern validation (e.g., ^v\d+\.\d+(\.\d+)?$)
  • options: Restricts to allowed values (e.g., ['dev', 'staging', 'prod'])

Empty spec handling:

# If no inputs needed, use empty spec (not blank)
spec: {}
---

Complete input specification reference: https://docs.gitlab.com/ci/inputs/

.gitlab-ci.yml for Testing

# Test the component works correctly
test-component:
  stage: test
  trigger:
    include:
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/my-component@$CI_COMMIT_SHA
        inputs:
          image_name: test-image
          image_tag: test-tag

.gitlab-ci.yml for Publishing

# Publish to catalog when a tag is created
release:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  rules:
    - if: $CI_COMMIT_TAG =~ /^\d+\.\d+\.\d+$/  # Semantic version tags only
  script:
    - echo "Releasing version $CI_COMMIT_TAG"
  release:
    tag_name: $CI_COMMIT_TAG
    description: "Release $CI_COMMIT_TAG"

Versioning requirements:

  • Use semantic versioning: 1.0.0, 2.3.4, etc.
  • Tag precedence: commit SHA > tag > branch
  • Partial versions supported: 1.2 matches latest 1.2.*
  • Use ~latest for absolute latest version (not recommended for production)

README.md Requirements

# Component Name

Brief description of what the component does.

## Components

### component-name

Description of component functionality.

#### Inputs

| Input | Type | Default | Required | Description |
|-------|------|---------|----------|-------------|
| stage | string | test | No | Pipeline stage |
| image_name | string | - | Yes | Docker image name |

#### Usage

\`\`\`yaml
include:
  - component: $CI_SERVER_FQDN/my-org/my-components/component-name@1.0.0
    inputs:
      image_name: myapp
      image_tag: v1.2.3
\`\`\`

## Contributing

Guidelines for contributing to this component.

Required sections:

  • Component summary and capabilities
  • Input documentation (use table format)
  • Usage examples with $CI_SERVER_FQDN (never hardcode domain)
  • For multi-component projects: table of contents and sections per component

Best Practices

Avoid Hardcoding

# ❌ BAD: Hardcoded values
script:
  - curl https://gitlab.example.com/api/v4/projects

# ✅ GOOD: Use built-in variables
script:
  - curl $CI_API_V4_URL/projects

Use predefined variables instead of hardcoded values:

  • $CI_SERVER_FQDN for domain names
  • $CI_API_V4_URL for API references
  • Inputs for user-configurable values

All predefined variables: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

Avoid Global Keywords

# ❌ BAD: Global default affects all jobs
default:
  image: alpine:latest

# ✅ GOOD: Define reusable config with extends
.base-config:
  image: alpine:latest

my-job:
  extends: .base-config

Global keywords like default: affect the entire pipeline, not just your component.

Component Usage Format

include:
  - component: <FQDN>/<project-path>/<component-name>@<version>
    inputs:
      field: value

Example:

include:
  - component: $CI_SERVER_FQDN/my-org/security/secret-detection@1.0.0
    inputs:
      stage: security-scan
      fail_on_detection: true

Common Mistakes

Mistake Consequence Fix
Missing templates/ directory Component not recognized Create templates/ at project root
Blank spec:inputs JSON schema validation error Use spec: {} if no inputs needed
Missing --- separator YAML parsing error Add --- between spec and jobs
Wrong input reference syntax Variable not interpolated Use $[[ inputs.name ]] not ${inputs.name}
No .gitlab-ci.yml testing Component breaks without detection Add test jobs that use the component
No .gitlab-ci.yml release job Manual publishing required Add automated release on version tags
Hardcoded domains Component not portable Use $CI_SERVER_FQDN and variables
Missing required inputs Pipeline error for users Either add default or document as required

Quick Start Workflow

  1. Create directory structure

    mkdir -p my-component/templates
    touch my-component/README.md
    touch my-component/LICENSE.md
    touch my-component/.gitlab-ci.yml
    
  2. Create component template

    • Create templates/my-component.yml
    • Add spec:inputs with validation
    • Add --- separator
    • Define jobs using $[[ inputs.field ]] syntax
  3. Document in README

    • Usage examples with $CI_SERVER_FQDN
    • Input table with types and descriptions
    • Contribution guidelines
  4. Configure testing

    • Add test job to .gitlab-ci.yml
    • Test component with various input combinations
  5. Configure publishing

    • Add release job triggered by semantic version tags
    • Test with a pre-release tag first
  6. Verify checklist

    • Run through Critical Requirements Checklist above
    • Ensure no hardcoded values
    • Confirm all inputs documented

Reference Documentation

For complete details, see: