Agents cicd-gitlab-components-dev
Develop reusable GitLab CI/CD components and templates. Use when creating CI/CD component libraries, building include templates, packaging components for the CI/CD Catalog, or designing organization-wide pipeline templates.
install
source · Clone the upstream repo
git clone https://github.com/aRustyDev/agents
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aRustyDev/agents "$T" && mkdir -p ~/.claude/skills && cp -r "$T/content/skills/cicd-gitlab-components-dev" ~/.claude/skills/arustydev-agents-cicd-gitlab-components-dev && rm -rf "$T"
manifest:
content/skills/cicd-gitlab-components-dev/SKILL.mdsource content
GitLab CI/CD Components Development
Guide for developing reusable GitLab CI/CD components and templates that can be shared across projects and organizations.
When to Use This Skill
- Creating reusable CI/CD component libraries
- Building include templates for shared pipelines
- Publishing to the GitLab CI/CD Catalog
- Designing organization-wide pipeline standards
- Packaging job templates and configurations
- Understanding component inputs, outputs, and specs
Component Types
CI/CD Components (Catalog)
Modern, versioned components with defined interfaces:
# templates/build/template.yml spec: inputs: stage: default: build image: default: node:20 script: type: array --- build-job: stage: $[[ inputs.stage ]] image: $[[ inputs.image ]] script: $[[ inputs.script ]] artifacts: paths: - dist/
Include Templates
Traditional YAML templates for sharing:
# templates/nodejs.yml .nodejs-base: image: node:20 cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ .nodejs-test: extends: .nodejs-base script: - npm ci - npm test
Component Structure
Directory Layout
my-component/ ├── templates/ │ ├── build/ │ │ └── template.yml # Component definition │ ├── test/ │ │ └── template.yml │ └── deploy/ │ └── template.yml ├── README.md └── .gitlab-ci.yml # Tests for the components
Component Specification
# templates/my-job/template.yml spec: inputs: # String input with default environment: description: 'Target environment' default: 'development' # Required string input app-name: description: 'Application name' # Boolean input run-tests: description: 'Whether to run tests' type: boolean default: true # Number input replicas: description: 'Number of replicas' type: number default: 1 # Array input extra-args: description: 'Additional arguments' type: array default: [] --- # Component implementation deploy-$[[ inputs.environment ]]: stage: deploy script: - echo "Deploying $[[ inputs.app-name ]] to $[[ inputs.environment ]]" - kubectl scale deployment/$[[ inputs.app-name ]] --replicas=$[[ inputs.replicas ]] rules: - if: $[[ inputs.run-tests ]] when: on_success
Input Types
String (Default)
spec: inputs: version: description: 'Version to deploy' default: 'latest' options: # Restrict to specific values - 'latest' - 'stable' - 'edge'
Boolean
spec: inputs: enable-cache: type: boolean default: true --- job: cache: - if: $[[ inputs.enable-cache ]] paths: - node_modules/
Number
spec: inputs: timeout-minutes: type: number default: 30 --- job: timeout: $[[ inputs.timeout-minutes ]] minutes
Array
spec: inputs: services: type: array default: - postgres:15 - redis:7 --- job: services: $[[ inputs.services ]]
Using Components
From CI/CD Catalog
include: - component: gitlab.com/my-org/components/build@1.0.0 inputs: image: node:20 script: - npm run build
From Project Repository
include: - component: $CI_SERVER_HOST/$CI_PROJECT_PATH/templates/build@$CI_COMMIT_SHA inputs: stage: build
Multiple Components
include: - component: gitlab.com/org/components/lint@1.0 inputs: config: .eslintrc.json - component: gitlab.com/org/components/test@1.0 inputs: coverage: true - component: gitlab.com/org/components/deploy@1.0 inputs: environment: production
Template Patterns
Hidden Jobs (Extends)
# templates/base.yml .base-job: image: alpine:latest before_script: - apk add --no-cache curl tags: - docker .test-base: extends: .base-job stage: test coverage: '/Coverage: \d+\.\d+%/' .deploy-base: extends: .base-job stage: deploy when: manual
Parameterized Templates
# templates/docker-build.yml spec: inputs: dockerfile: default: Dockerfile context: default: '.' registry: default: $CI_REGISTRY image-name: default: $CI_PROJECT_PATH --- docker-build: stage: build image: docker:24 services: - docker:24-dind variables: DOCKER_TLS_CERTDIR: "/certs" script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $[[ inputs.registry ]] - docker build -f $[[ inputs.dockerfile ]] -t $[[ inputs.registry ]]/$[[ inputs.image-name ]]:$CI_COMMIT_SHA $[[ inputs.context ]] - docker push $[[ inputs.registry ]]/$[[ inputs.image-name ]]:$CI_COMMIT_SHA
Job Generator Pattern
spec: inputs: environments: type: array default: - staging - production --- # Generates multiple jobs from array .deploy-template: stage: deploy script: - ./deploy.sh $ENVIRONMENT deploy-staging: extends: .deploy-template variables: ENVIRONMENT: staging rules: - if: $CI_COMMIT_BRANCH == "main" deploy-production: extends: .deploy-template variables: ENVIRONMENT: production when: manual rules: - if: $CI_COMMIT_BRANCH == "main"
CI/CD Catalog Publishing
Project Configuration
# .gitlab-ci.yml in component project stages: - test - release test-components: stage: test script: - gitlab-ci-local --list # Validate components create-release: stage: release script: - echo "Creating release" release: tag_name: $CI_COMMIT_TAG description: 'Release $CI_COMMIT_TAG' rules: - if: $CI_COMMIT_TAG
Catalog Metadata
# In project settings or .gitlab/ci-component.yml --- name: My CI/CD Components description: Reusable components for CI/CD icon: 🚀 categories: - Build - Test - Deploy
Versioning
# Semantic versioning for components git tag -a v1.0.0 -m "Initial release" git push origin v1.0.0
Include Patterns
Local Includes
include: - local: '/templates/base.yml' - local: '/templates/nodejs.yml'
Project Includes
include: - project: 'my-group/ci-templates' ref: v1.0.0 file: - '/templates/nodejs.yml' - '/templates/docker.yml'
Remote Includes
include: - remote: 'https://example.com/ci/templates/standard.yml'
Template Includes
include: - template: Security/SAST.gitlab-ci.yml - template: Code-Quality.gitlab-ci.yml
Testing Components
Component Validation
# .gitlab-ci.yml test:component-syntax: stage: test script: - | for template in templates/*/template.yml; do echo "Validating $template" yq eval '.' "$template" > /dev/null done
Integration Testing
test:component-integration: stage: test trigger: include: - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/templates/build@$CI_COMMIT_SHA inputs: script: - echo "Test passed"
Local Testing
# Install gitlab-ci-local npm install -g gitlab-ci-local # Test pipeline with components gitlab-ci-local --list gitlab-ci-local test
Advanced Patterns
Conditional Component Content
spec: inputs: enable-sast: type: boolean default: false --- build: stage: build script: - npm run build # Only included when enable-sast is true sast-scan: rules: - if: $[[ inputs.enable-sast ]] stage: test script: - npm audit
Composition of Components
# meta-component that combines others spec: inputs: nodejs-version: default: '20' run-security: type: boolean default: true --- include: - component: gitlab.com/org/components/nodejs-setup@1.0 inputs: version: $[[ inputs.nodejs-version ]] - component: gitlab.com/org/components/security-scan@1.0 rules: - if: $[[ inputs.run-security ]]
Dynamic Child Pipelines
spec: inputs: services: type: array --- generate-pipeline: stage: build script: - | cat > child-pipeline.yml << EOF stages: - deploy EOF for service in $[[ inputs.services | join(" ") ]]; do cat >> child-pipeline.yml << EOF deploy-$service: stage: deploy script: - ./deploy.sh $service EOF done artifacts: paths: - child-pipeline.yml trigger-deploy: stage: deploy trigger: include: - artifact: child-pipeline.yml job: generate-pipeline
Documentation
Component README
# Component Name Brief description of what this component does. ## Usage \`\`\`yaml include: - component: gitlab.com/org/my-component@1.0.0 inputs: param1: value1 \`\`\` ## Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | `param1` | string | `default` | What it does | | `enable-x` | boolean | `true` | Whether to enable X | ## Examples ### Basic Usage \`\`\`yaml include: - component: gitlab.com/org/my-component@1.0.0 \`\`\` ### Advanced Usage \`\`\`yaml include: - component: gitlab.com/org/my-component@1.0.0 inputs: param1: custom-value enable-x: false \`\`\` ## Outputs This component creates the following jobs: - `build`: Builds the application - `test`: Runs tests
Debugging Checklist
- Verify component spec syntax (inputs, types, defaults)
- Check
interpolation syntax (not$[[ ]]
)${{ }} - Ensure inputs are passed correctly when including
- Validate YAML structure with linter
- Test component locally with gitlab-ci-local
- Verify version tags exist for referenced components
- Check project visibility allows component access