Agent skill
building-gitlab-ci-components
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 this agent skill to your Project
npx add-skill https://github.com/nagyv/claude-commands/tree/main/skills/building-gitlab-ci-components
SKILL.md
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.ymlfiles or subdirectories withtemplate.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:inputssyntax 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_FQDNand 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
defaultare 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 typeregex: 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.2matches latest1.2.* - Use
~latestfor 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_FQDNfor domain names$CI_API_V4_URLfor 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
-
Create directory structure
bashmkdir -p my-component/templates touch my-component/README.md touch my-component/LICENSE.md touch my-component/.gitlab-ci.yml -
Create component template
- Create
templates/my-component.yml - Add
spec:inputswith validation - Add
---separator - Define jobs using
$[[ inputs.field ]]syntax
- Create
-
Document in README
- Usage examples with
$CI_SERVER_FQDN - Input table with types and descriptions
- Contribution guidelines
- Usage examples with
-
Configure testing
- Add test job to
.gitlab-ci.yml - Test component with various input combinations
- Add test job to
-
Configure publishing
- Add release job triggered by semantic version tags
- Test with a pre-release tag first
-
Verify checklist
- Run through Critical Requirements Checklist above
- Ensure no hardcoded values
- Confirm all inputs documented
Reference Documentation
For complete details, see:
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
creating-db-analytics-analysis
Use when creating new multi-subscriber database analyses in db-analytics project - guides the complete workflow from database exploration through CI integration, using subagents for each step and ensuring all changes are on a feature branch
database-migration-deployment
Use when deploying database-backed services to Kubernetes that require schema migrations before app startup, especially with multiple replicas, Prisma/Alembic/Liquibase migrations, or when migration timing and coordination is critical to prevent schema mismatches
edit-article
Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.
handoff
Compact the current conversation into a handoff document for another agent to pick up.
obsidian-vault
Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.
setup-pre-commit
Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.
Didn't find tool you were looking for?