mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
.
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
---
|
||||
name: azure-devops
|
||||
description: Set up Azure Pipelines for CI/CD, configure build and release pipelines, manage Azure DevOps projects, and integrate with Azure services. Use when working with Azure DevOps Services or Server for enterprise DevOps workflows.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Azure DevOps Pipelines
|
||||
|
||||
Build, test, and deploy applications using Azure Pipelines with YAML or classic editor.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Creating CI/CD pipelines in Azure DevOps
|
||||
- Configuring build and release stages
|
||||
- Managing Azure DevOps service connections
|
||||
- Deploying to Azure or other cloud platforms
|
||||
- Setting up multi-stage YAML pipelines
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Azure DevOps organization and project
|
||||
- Service connections for target environments
|
||||
- Basic YAML understanding
|
||||
- Azure subscription (for Azure deployments)
|
||||
|
||||
## YAML Pipeline Structure
|
||||
|
||||
Create `azure-pipelines.yml` in repository root:
|
||||
|
||||
```yaml
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- develop
|
||||
paths:
|
||||
include:
|
||||
- src/*
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
variables:
|
||||
buildConfiguration: 'Release'
|
||||
nodeVersion: '20.x'
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
jobs:
|
||||
- job: BuildJob
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
- script: |
|
||||
npm ci
|
||||
npm run build
|
||||
displayName: 'Build application'
|
||||
- publish: $(Build.ArtifactStagingDirectory)
|
||||
artifact: drop
|
||||
|
||||
- stage: Deploy
|
||||
dependsOn: Build
|
||||
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
|
||||
jobs:
|
||||
- deployment: DeployWeb
|
||||
environment: 'production'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- script: echo Deploying to production
|
||||
```
|
||||
|
||||
## Triggers
|
||||
|
||||
### Branch Triggers
|
||||
|
||||
```yaml
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
exclude:
|
||||
- feature/*
|
||||
tags:
|
||||
include:
|
||||
- v*
|
||||
```
|
||||
|
||||
### Pull Request Triggers
|
||||
|
||||
```yaml
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
paths:
|
||||
include:
|
||||
- src/*
|
||||
exclude:
|
||||
- docs/*
|
||||
```
|
||||
|
||||
### Scheduled Triggers
|
||||
|
||||
```yaml
|
||||
schedules:
|
||||
- cron: '0 2 * * *'
|
||||
displayName: 'Nightly build'
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: true
|
||||
```
|
||||
|
||||
## Jobs and Stages
|
||||
|
||||
### Parallel Jobs
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- stage: Test
|
||||
jobs:
|
||||
- job: UnitTests
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: npm run test:unit
|
||||
|
||||
- job: IntegrationTests
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: npm run test:integration
|
||||
```
|
||||
|
||||
### Matrix Strategy
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
- job: Build
|
||||
strategy:
|
||||
matrix:
|
||||
linux:
|
||||
vmImage: 'ubuntu-latest'
|
||||
windows:
|
||||
vmImage: 'windows-latest'
|
||||
mac:
|
||||
vmImage: 'macos-latest'
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
- script: npm test
|
||||
```
|
||||
|
||||
### Job Dependencies
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- stage: Build
|
||||
jobs:
|
||||
- job: A
|
||||
steps:
|
||||
- script: echo Job A
|
||||
- job: B
|
||||
dependsOn: A
|
||||
steps:
|
||||
- script: echo Job B
|
||||
```
|
||||
|
||||
## Variables and Parameters
|
||||
|
||||
### Variable Groups
|
||||
|
||||
```yaml
|
||||
variables:
|
||||
- group: 'production-secrets'
|
||||
- name: buildConfiguration
|
||||
value: 'Release'
|
||||
```
|
||||
|
||||
### Runtime Parameters
|
||||
|
||||
```yaml
|
||||
parameters:
|
||||
- name: environment
|
||||
displayName: 'Environment'
|
||||
type: string
|
||||
default: 'dev'
|
||||
values:
|
||||
- dev
|
||||
- staging
|
||||
- prod
|
||||
|
||||
stages:
|
||||
- stage: Deploy
|
||||
variables:
|
||||
env: ${{ parameters.environment }}
|
||||
jobs:
|
||||
- job: Deploy
|
||||
steps:
|
||||
- script: echo "Deploying to $(env)"
|
||||
```
|
||||
|
||||
### Secret Variables
|
||||
|
||||
```yaml
|
||||
variables:
|
||||
- name: mySecret
|
||||
value: $(SECRET_FROM_PIPELINE) # Set in pipeline settings
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
echo "Using secret"
|
||||
./deploy.sh
|
||||
env:
|
||||
API_KEY: $(mySecret)
|
||||
```
|
||||
|
||||
## Templates
|
||||
|
||||
### Job Template
|
||||
|
||||
```yaml
|
||||
# templates/build-job.yml
|
||||
parameters:
|
||||
- name: nodeVersion
|
||||
default: '20'
|
||||
|
||||
jobs:
|
||||
- job: Build
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: ${{ parameters.nodeVersion }}
|
||||
- script: npm ci && npm run build
|
||||
```
|
||||
|
||||
### Using Templates
|
||||
|
||||
```yaml
|
||||
# azure-pipelines.yml
|
||||
stages:
|
||||
- stage: Build
|
||||
jobs:
|
||||
- template: templates/build-job.yml
|
||||
parameters:
|
||||
nodeVersion: '20'
|
||||
```
|
||||
|
||||
### Stage Template
|
||||
|
||||
```yaml
|
||||
# templates/deploy-stage.yml
|
||||
parameters:
|
||||
- name: environment
|
||||
type: string
|
||||
- name: serviceConnection
|
||||
type: string
|
||||
|
||||
stages:
|
||||
- stage: Deploy_${{ parameters.environment }}
|
||||
jobs:
|
||||
- deployment: Deploy
|
||||
environment: ${{ parameters.environment }}
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- task: AzureWebApp@1
|
||||
inputs:
|
||||
azureSubscription: ${{ parameters.serviceConnection }}
|
||||
appName: 'myapp-${{ parameters.environment }}'
|
||||
```
|
||||
|
||||
## Deployments
|
||||
|
||||
### Environment Deployments
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- stage: DeployStaging
|
||||
jobs:
|
||||
- deployment: DeployWeb
|
||||
environment: 'staging'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- download: current
|
||||
artifact: drop
|
||||
- script: ./deploy.sh staging
|
||||
```
|
||||
|
||||
### Approval Gates
|
||||
|
||||
Configure in Azure DevOps UI:
|
||||
1. Go to Environments
|
||||
2. Select environment
|
||||
3. Add approval check
|
||||
4. Configure approvers
|
||||
|
||||
### Rolling Deployment
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
- deployment: Deploy
|
||||
environment: 'production'
|
||||
strategy:
|
||||
rolling:
|
||||
maxParallel: 2
|
||||
deploy:
|
||||
steps:
|
||||
- script: ./deploy.sh
|
||||
```
|
||||
|
||||
## Azure Service Tasks
|
||||
|
||||
### Azure Web App Deployment
|
||||
|
||||
```yaml
|
||||
- task: AzureWebApp@1
|
||||
inputs:
|
||||
azureSubscription: 'my-azure-connection'
|
||||
appType: 'webAppLinux'
|
||||
appName: 'my-web-app'
|
||||
package: '$(Pipeline.Workspace)/drop/*.zip'
|
||||
```
|
||||
|
||||
### Azure Container Apps
|
||||
|
||||
```yaml
|
||||
- task: AzureContainerApps@1
|
||||
inputs:
|
||||
azureSubscription: 'my-azure-connection'
|
||||
containerAppName: 'my-container-app'
|
||||
resourceGroup: 'my-rg'
|
||||
imageToDeploy: 'myregistry.azurecr.io/myapp:$(Build.BuildId)'
|
||||
```
|
||||
|
||||
### Azure Kubernetes Service
|
||||
|
||||
```yaml
|
||||
- task: KubernetesManifest@0
|
||||
inputs:
|
||||
action: 'deploy'
|
||||
kubernetesServiceConnection: 'my-aks-connection'
|
||||
namespace: 'default'
|
||||
manifests: |
|
||||
$(Pipeline.Workspace)/manifests/deployment.yml
|
||||
$(Pipeline.Workspace)/manifests/service.yml
|
||||
containers: |
|
||||
myregistry.azurecr.io/myapp:$(Build.BuildId)
|
||||
```
|
||||
|
||||
## Docker Builds
|
||||
|
||||
```yaml
|
||||
- task: Docker@2
|
||||
inputs:
|
||||
containerRegistry: 'my-acr-connection'
|
||||
repository: 'myapp'
|
||||
command: 'buildAndPush'
|
||||
Dockerfile: '**/Dockerfile'
|
||||
tags: |
|
||||
$(Build.BuildId)
|
||||
latest
|
||||
```
|
||||
|
||||
## Self-Hosted Agents
|
||||
|
||||
### Install Agent
|
||||
|
||||
```bash
|
||||
# Download agent
|
||||
mkdir myagent && cd myagent
|
||||
curl -o vsts-agent.tar.gz https://vstsagentpackage.azureedge.net/agent/3.227.2/vsts-agent-linux-x64-3.227.2.tar.gz
|
||||
tar zxvf vsts-agent.tar.gz
|
||||
|
||||
# Configure
|
||||
./config.sh --url https://dev.azure.com/myorg --auth pat --token PAT_TOKEN --pool default
|
||||
|
||||
# Run as service
|
||||
sudo ./svc.sh install
|
||||
sudo ./svc.sh start
|
||||
```
|
||||
|
||||
### Use Self-Hosted Pool
|
||||
|
||||
```yaml
|
||||
pool:
|
||||
name: 'my-self-hosted-pool'
|
||||
demands:
|
||||
- docker
|
||||
- Agent.OS -equals Linux
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Service Connection Fails
|
||||
**Problem**: Cannot authenticate to Azure
|
||||
**Solution**: Verify service principal permissions, check connection in project settings
|
||||
|
||||
### Issue: Artifact Not Found
|
||||
**Problem**: Download artifact fails
|
||||
**Solution**: Ensure publish task ran successfully, check artifact name matches
|
||||
|
||||
### Issue: Environment Not Found
|
||||
**Problem**: Deployment to environment fails
|
||||
**Solution**: Create environment in Pipelines > Environments first
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use YAML pipelines over classic editor
|
||||
- Implement templates for reusable components
|
||||
- Use variable groups for shared configuration
|
||||
- Configure environment approvals for production
|
||||
- Use service connections with minimal permissions
|
||||
- Implement artifact versioning
|
||||
- Cache dependencies for faster builds
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [github-actions](../github-actions/) - GitHub CI/CD alternative
|
||||
- [terraform-azure](../../../infrastructure/cloud-azure/terraform-azure/) - Azure IaC
|
||||
- [azure-aks](../../../infrastructure/cloud-azure/azure-aks/) - AKS deployments
|
||||
@@ -0,0 +1,450 @@
|
||||
---
|
||||
name: circleci
|
||||
description: Configure CircleCI workflows and orbs for continuous integration and deployment. Create config.yml pipelines, use orbs for reusable configurations, and optimize build performance. Use when working with CircleCI for CI/CD automation.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# CircleCI
|
||||
|
||||
Build, test, and deploy applications using CircleCI's cloud-native CI/CD platform.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Setting up CI/CD pipelines with CircleCI
|
||||
- Using orbs for reusable configuration
|
||||
- Optimizing build times with caching and parallelism
|
||||
- Configuring CircleCI workflows and approvals
|
||||
- Managing CircleCI contexts and secrets
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- CircleCI account connected to repository
|
||||
- Project enabled in CircleCI dashboard
|
||||
- Basic YAML understanding
|
||||
|
||||
## Configuration File
|
||||
|
||||
Create `.circleci/config.yml`:
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
node: circleci/node@5.2
|
||||
docker: circleci/docker@2.4
|
||||
|
||||
executors:
|
||||
default:
|
||||
docker:
|
||||
- image: cimg/node:20.10
|
||||
working_directory: ~/project
|
||||
|
||||
jobs:
|
||||
build:
|
||||
executor: default
|
||||
steps:
|
||||
- checkout
|
||||
- node/install-packages:
|
||||
pkg-manager: npm
|
||||
- run:
|
||||
name: Build application
|
||||
command: npm run build
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- dist
|
||||
|
||||
test:
|
||||
executor: default
|
||||
steps:
|
||||
- checkout
|
||||
- node/install-packages:
|
||||
pkg-manager: npm
|
||||
- run:
|
||||
name: Run tests
|
||||
command: npm test
|
||||
|
||||
deploy:
|
||||
executor: default
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Deploy
|
||||
command: ./deploy.sh
|
||||
|
||||
workflows:
|
||||
build-test-deploy:
|
||||
jobs:
|
||||
- build
|
||||
- test:
|
||||
requires:
|
||||
- build
|
||||
- deploy:
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
```
|
||||
|
||||
## Executors
|
||||
|
||||
### Docker Executor
|
||||
|
||||
```yaml
|
||||
executors:
|
||||
node:
|
||||
docker:
|
||||
- image: cimg/node:20.10
|
||||
- image: cimg/postgres:15.0
|
||||
environment:
|
||||
POSTGRES_USER: test
|
||||
POSTGRES_DB: testdb
|
||||
working_directory: ~/app
|
||||
```
|
||||
|
||||
### Machine Executor
|
||||
|
||||
```yaml
|
||||
executors:
|
||||
linux-machine:
|
||||
machine:
|
||||
image: ubuntu-2204:current
|
||||
resource_class: large
|
||||
```
|
||||
|
||||
### macOS Executor
|
||||
|
||||
```yaml
|
||||
executors:
|
||||
macos:
|
||||
macos:
|
||||
xcode: "15.0.0"
|
||||
resource_class: macos.m1.medium.gen1
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
### Dependency Caching
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-deps-{{ checksum "package-lock.json" }}
|
||||
- v1-deps-
|
||||
- run: npm ci
|
||||
- save_cache:
|
||||
key: v1-deps-{{ checksum "package-lock.json" }}
|
||||
paths:
|
||||
- node_modules
|
||||
```
|
||||
|
||||
### Multi-Key Caching
|
||||
|
||||
```yaml
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-{{ .Branch }}-{{ checksum "package-lock.json" }}
|
||||
- v1-{{ .Branch }}-
|
||||
- v1-main-
|
||||
- v1-
|
||||
```
|
||||
|
||||
## Workspaces
|
||||
|
||||
### Persist Data
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
steps:
|
||||
- checkout
|
||||
- run: npm run build
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- dist
|
||||
- node_modules
|
||||
|
||||
deploy:
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/project
|
||||
- run: ./deploy.sh
|
||||
```
|
||||
|
||||
## Parallelism
|
||||
|
||||
### Test Splitting
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
parallelism: 4
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Run tests
|
||||
command: |
|
||||
TESTFILES=$(circleci tests glob "test/**/*.test.js" | circleci tests split --split-by=timings)
|
||||
npm test -- $TESTFILES
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### Sequential Jobs
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
pipeline:
|
||||
jobs:
|
||||
- build
|
||||
- test:
|
||||
requires:
|
||||
- build
|
||||
- deploy:
|
||||
requires:
|
||||
- test
|
||||
```
|
||||
|
||||
### Parallel Jobs
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
pipeline:
|
||||
jobs:
|
||||
- build
|
||||
- test-unit:
|
||||
requires:
|
||||
- build
|
||||
- test-integration:
|
||||
requires:
|
||||
- build
|
||||
- deploy:
|
||||
requires:
|
||||
- test-unit
|
||||
- test-integration
|
||||
```
|
||||
|
||||
### Manual Approval
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
deploy-prod:
|
||||
jobs:
|
||||
- build
|
||||
- test
|
||||
- hold:
|
||||
type: approval
|
||||
requires:
|
||||
- test
|
||||
- deploy-production:
|
||||
requires:
|
||||
- hold
|
||||
```
|
||||
|
||||
### Scheduled Workflows
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
nightly:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 2 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
jobs:
|
||||
- build
|
||||
- test
|
||||
```
|
||||
|
||||
### Branch Filtering
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
build-deploy:
|
||||
jobs:
|
||||
- build:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
- /feature-.*/
|
||||
- deploy:
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
tags:
|
||||
only: /^v.*/
|
||||
```
|
||||
|
||||
## Orbs
|
||||
|
||||
### Using Orbs
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
aws-cli: circleci/aws-cli@4.1
|
||||
kubernetes: circleci/kubernetes@1.3
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
executor: aws-cli/default
|
||||
steps:
|
||||
- aws-cli/setup:
|
||||
aws_access_key_id: AWS_ACCESS_KEY_ID
|
||||
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
|
||||
- kubernetes/install-kubectl
|
||||
- run: kubectl apply -f k8s/
|
||||
```
|
||||
|
||||
### Common Orbs
|
||||
|
||||
```yaml
|
||||
orbs:
|
||||
node: circleci/node@5.2 # Node.js
|
||||
docker: circleci/docker@2.4 # Docker builds
|
||||
aws-cli: circleci/aws-cli@4.1 # AWS CLI
|
||||
aws-ecr: circleci/aws-ecr@9.0 # ECR push
|
||||
aws-ecs: circleci/aws-ecs@4.0 # ECS deploy
|
||||
gcp-cli: circleci/gcp-cli@3.1 # GCP CLI
|
||||
kubernetes: circleci/kubernetes@1.3 # K8s deploy
|
||||
slack: circleci/slack@4.12 # Notifications
|
||||
```
|
||||
|
||||
## Docker Builds
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
docker: circleci/docker@2.4
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
executor: docker/docker
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
version: 20.10.24
|
||||
- checkout
|
||||
- docker/check
|
||||
- docker/build:
|
||||
image: myorg/myapp
|
||||
tag: $CIRCLE_SHA1
|
||||
- docker/push:
|
||||
image: myorg/myapp
|
||||
tag: $CIRCLE_SHA1
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Project Variables
|
||||
|
||||
Set in CircleCI Project Settings > Environment Variables
|
||||
|
||||
### Contexts
|
||||
|
||||
```yaml
|
||||
workflows:
|
||||
deploy:
|
||||
jobs:
|
||||
- deploy-staging:
|
||||
context: staging-secrets
|
||||
- deploy-production:
|
||||
context: production-secrets
|
||||
```
|
||||
|
||||
### Using Variables
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
steps:
|
||||
- run:
|
||||
name: Deploy
|
||||
command: |
|
||||
aws s3 sync dist/ s3://$S3_BUCKET
|
||||
environment:
|
||||
AWS_DEFAULT_REGION: us-east-1
|
||||
```
|
||||
|
||||
## Artifacts and Test Results
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
steps:
|
||||
- run:
|
||||
name: Run tests
|
||||
command: npm test -- --coverage
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
- store_artifacts:
|
||||
path: coverage
|
||||
destination: coverage-report
|
||||
```
|
||||
|
||||
## Resource Classes
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: cimg/node:20.10
|
||||
resource_class: large # 4 vCPU, 8GB RAM
|
||||
steps:
|
||||
- checkout
|
||||
- run: npm run build
|
||||
|
||||
# Available classes:
|
||||
# small: 1 vCPU, 2GB RAM
|
||||
# medium: 2 vCPU, 4GB RAM (default)
|
||||
# large: 4 vCPU, 8GB RAM
|
||||
# xlarge: 8 vCPU, 16GB RAM
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Cache Not Restoring
|
||||
**Problem**: Cache misses on every build
|
||||
**Solution**: Verify cache key format, ensure checksum file hasn't changed
|
||||
|
||||
### Issue: Workspace Attach Fails
|
||||
**Problem**: Cannot find persisted workspace
|
||||
**Solution**: Ensure persist_to_workspace job completed, check paths
|
||||
|
||||
### Issue: Docker Layer Caching
|
||||
**Problem**: Docker builds are slow
|
||||
**Solution**: Enable Docker Layer Caching in project settings (paid feature)
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use orbs for common tasks
|
||||
- Implement aggressive caching strategies
|
||||
- Use workspaces for sharing data between jobs
|
||||
- Split tests with parallelism for faster builds
|
||||
- Use contexts for environment-specific secrets
|
||||
- Define reusable executors
|
||||
- Store test results for insights
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [github-actions](../github-actions/) - GitHub CI/CD
|
||||
- [docker-management](../../containers/docker-management/) - Container builds
|
||||
- [aws-ecs-fargate](../../../infrastructure/cloud-aws/aws-ecs-fargate/) - ECS deployments
|
||||
@@ -0,0 +1,344 @@
|
||||
---
|
||||
name: github-actions
|
||||
description: Build, test, and deploy applications using GitHub Actions workflows. Create CI/CD pipelines, configure runners, manage secrets, and automate software delivery. Use when working with GitHub repositories, automating builds, running tests, or deploying applications.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# GitHub Actions
|
||||
|
||||
Automate software workflows directly in your GitHub repository with GitHub Actions.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Setting up CI/CD pipelines for GitHub repositories
|
||||
- Automating build, test, and deployment workflows
|
||||
- Creating reusable workflow components
|
||||
- Configuring self-hosted runners
|
||||
- Managing workflow secrets and variables
|
||||
- Debugging failed workflow runs
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- GitHub repository with write access
|
||||
- Understanding of YAML syntax
|
||||
- For self-hosted runners: server with Docker (optional)
|
||||
|
||||
## Workflow File Structure
|
||||
|
||||
Workflows are defined in `.github/workflows/` directory:
|
||||
|
||||
```yaml
|
||||
name: CI Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
## Common Triggers
|
||||
|
||||
### Push and Pull Request
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'package.json'
|
||||
pull_request:
|
||||
branches: [main]
|
||||
```
|
||||
|
||||
### Scheduled Runs
|
||||
|
||||
```yaml
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # Daily at 2 AM UTC
|
||||
```
|
||||
|
||||
### Manual Dispatch
|
||||
|
||||
```yaml
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Deployment environment'
|
||||
required: true
|
||||
default: 'staging'
|
||||
type: choice
|
||||
options:
|
||||
- staging
|
||||
- production
|
||||
```
|
||||
|
||||
## Job Configuration
|
||||
|
||||
### Matrix Builds
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
### Job Dependencies
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: npm run build
|
||||
|
||||
test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: npm test
|
||||
|
||||
deploy:
|
||||
needs: [build, test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: ./deploy.sh
|
||||
```
|
||||
|
||||
### Environment Protection
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
url: https://example.com
|
||||
steps:
|
||||
- run: ./deploy.sh
|
||||
```
|
||||
|
||||
## Secrets and Variables
|
||||
|
||||
### Using Secrets
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: Deploy
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
run: aws s3 sync ./dist s3://my-bucket
|
||||
```
|
||||
|
||||
### Using Variables
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: Build
|
||||
env:
|
||||
API_URL: ${{ vars.API_URL }}
|
||||
run: npm run build
|
||||
```
|
||||
|
||||
## Caching Dependencies
|
||||
|
||||
```yaml
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
```
|
||||
|
||||
## Artifacts
|
||||
|
||||
### Upload Artifacts
|
||||
|
||||
```yaml
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output
|
||||
path: dist/
|
||||
retention-days: 5
|
||||
```
|
||||
|
||||
### Download Artifacts
|
||||
|
||||
```yaml
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-output
|
||||
path: dist/
|
||||
```
|
||||
|
||||
## Docker Builds
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
```
|
||||
|
||||
## Reusable Workflows
|
||||
|
||||
### Define Reusable Workflow
|
||||
|
||||
```yaml
|
||||
# .github/workflows/reusable-deploy.yml
|
||||
name: Reusable Deploy
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
deploy_key:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment: ${{ inputs.environment }}
|
||||
steps:
|
||||
- run: echo "Deploying to ${{ inputs.environment }}"
|
||||
```
|
||||
|
||||
### Call Reusable Workflow
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy-staging:
|
||||
uses: ./.github/workflows/reusable-deploy.yml
|
||||
with:
|
||||
environment: staging
|
||||
secrets:
|
||||
deploy_key: ${{ secrets.STAGING_KEY }}
|
||||
```
|
||||
|
||||
## Self-Hosted Runners
|
||||
|
||||
### Register Runner
|
||||
|
||||
```bash
|
||||
# Download runner
|
||||
mkdir actions-runner && cd actions-runner
|
||||
curl -o actions-runner-linux-x64.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz
|
||||
tar xzf actions-runner-linux-x64.tar.gz
|
||||
|
||||
# Configure
|
||||
./config.sh --url https://github.com/OWNER/REPO --token TOKEN
|
||||
|
||||
# Run
|
||||
./run.sh
|
||||
```
|
||||
|
||||
### Use Self-Hosted Runner
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
```
|
||||
|
||||
## Debugging Workflows
|
||||
|
||||
### Enable Debug Logging
|
||||
|
||||
Set repository secrets:
|
||||
- `ACTIONS_RUNNER_DEBUG`: `true`
|
||||
- `ACTIONS_STEP_DEBUG`: `true`
|
||||
|
||||
### Debug Step
|
||||
|
||||
```yaml
|
||||
- name: Debug
|
||||
run: |
|
||||
echo "GitHub context: ${{ toJson(github) }}"
|
||||
echo "Job context: ${{ toJson(job) }}"
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Workflow Not Triggering
|
||||
**Problem**: Workflow doesn't run on push/PR
|
||||
**Solution**: Check branch filters, path filters, and ensure workflow file is on the default branch
|
||||
|
||||
### Issue: Permission Denied
|
||||
**Problem**: Actions can't push or create PRs
|
||||
**Solution**: Configure `permissions` in workflow or update repository settings
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
```
|
||||
|
||||
### Issue: Cache Not Restoring
|
||||
**Problem**: Cache misses despite existing cache
|
||||
**Solution**: Verify cache key matches exactly, check runner OS
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Pin action versions to specific commits or tags
|
||||
- Use caching for dependencies to speed up builds
|
||||
- Minimize secrets exposure with environment scoping
|
||||
- Use matrix builds for cross-platform testing
|
||||
- Implement proper error handling with `continue-on-error`
|
||||
- Keep workflows DRY with reusable workflows and composite actions
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [gitlab-ci](../gitlab-ci/) - GitLab CI/CD alternative
|
||||
- [docker-management](../../containers/docker-management/) - Container builds
|
||||
- [semantic-versioning](../../release/semantic-versioning/) - Automated releases
|
||||
@@ -0,0 +1,125 @@
|
||||
# GitHub Actions Workflow Patterns
|
||||
|
||||
## Reusable Workflows
|
||||
|
||||
### Caller Workflow
|
||||
```yaml
|
||||
jobs:
|
||||
call-workflow:
|
||||
uses: org/repo/.github/workflows/reusable.yml@main
|
||||
with:
|
||||
environment: production
|
||||
secrets:
|
||||
deploy_key: ${{ secrets.DEPLOY_KEY }}
|
||||
```
|
||||
|
||||
### Reusable Workflow
|
||||
```yaml
|
||||
# .github/workflows/reusable.yml
|
||||
name: Reusable Deploy
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
environment:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
deploy_key:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./deploy.sh ${{ inputs.environment }}
|
||||
```
|
||||
|
||||
## Matrix Builds
|
||||
|
||||
```yaml
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
node: [18, 20]
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
node: 18
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
node: 20
|
||||
experimental: true
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
```
|
||||
|
||||
## Environment Protection
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
url: https://example.com
|
||||
steps:
|
||||
- run: ./deploy.sh
|
||||
```
|
||||
|
||||
## Concurrency Control
|
||||
|
||||
```yaml
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
```
|
||||
|
||||
## Job Dependencies
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps: [...]
|
||||
|
||||
test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps: [...]
|
||||
|
||||
deploy:
|
||||
needs: [build, test]
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
```
|
||||
|
||||
## Artifact Sharing
|
||||
|
||||
```yaml
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-output
|
||||
path: dist/
|
||||
retention-days: 5
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-output
|
||||
path: dist/
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
```yaml
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
```
|
||||
@@ -0,0 +1,315 @@
|
||||
---
|
||||
name: gitlab-ci
|
||||
description: Configure GitLab CI/CD pipelines and runners for automated building, testing, and deployment. Create .gitlab-ci.yml configurations, manage runners, and implement DevOps workflows. Use when working with GitLab repositories or self-hosted GitLab instances.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# GitLab CI/CD
|
||||
|
||||
Automate your software delivery pipeline with GitLab's integrated CI/CD system.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Setting up CI/CD pipelines in GitLab
|
||||
- Configuring GitLab runners (shared or self-hosted)
|
||||
- Creating multi-stage deployment pipelines
|
||||
- Implementing GitLab Auto DevOps
|
||||
- Managing CI/CD variables and secrets
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- GitLab repository (gitlab.com or self-hosted)
|
||||
- Basic understanding of YAML
|
||||
- For self-hosted runners: Linux server or Kubernetes cluster
|
||||
|
||||
## Pipeline Configuration
|
||||
|
||||
Create `.gitlab-ci.yml` in repository root:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
NODE_VERSION: "20"
|
||||
|
||||
build:
|
||||
stage: build
|
||||
image: node:${NODE_VERSION}
|
||||
script:
|
||||
- npm ci
|
||||
- npm run build
|
||||
artifacts:
|
||||
paths:
|
||||
- dist/
|
||||
expire_in: 1 hour
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image: node:${NODE_VERSION}
|
||||
script:
|
||||
- npm ci
|
||||
- npm test
|
||||
coverage: '/Coverage: \d+\.\d+%/'
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- ./deploy.sh
|
||||
environment:
|
||||
name: production
|
||||
url: https://example.com
|
||||
only:
|
||||
- main
|
||||
```
|
||||
|
||||
## Job Configuration
|
||||
|
||||
### Rules-Based Execution
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
script: ./deploy.sh
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
when: manual
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
when: never
|
||||
- when: on_success
|
||||
```
|
||||
|
||||
### Parallel Jobs
|
||||
|
||||
```yaml
|
||||
test:
|
||||
stage: test
|
||||
parallel: 3
|
||||
script:
|
||||
- npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
|
||||
```
|
||||
|
||||
### Matrix Builds
|
||||
|
||||
```yaml
|
||||
test:
|
||||
stage: test
|
||||
parallel:
|
||||
matrix:
|
||||
- NODE_VERSION: ["18", "20", "22"]
|
||||
OS: ["alpine", "slim"]
|
||||
image: node:${NODE_VERSION}-${OS}
|
||||
script:
|
||||
- npm test
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
key:
|
||||
files:
|
||||
- package-lock.json
|
||||
paths:
|
||||
- node_modules/
|
||||
policy: pull-push
|
||||
|
||||
build:
|
||||
cache:
|
||||
key: build-cache
|
||||
paths:
|
||||
- .cache/
|
||||
policy: pull
|
||||
```
|
||||
|
||||
## Artifacts
|
||||
|
||||
```yaml
|
||||
build:
|
||||
artifacts:
|
||||
paths:
|
||||
- dist/
|
||||
- coverage/
|
||||
reports:
|
||||
junit: junit.xml
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: coverage/cobertura.xml
|
||||
expire_in: 1 week
|
||||
when: always
|
||||
```
|
||||
|
||||
## Environments and Deployments
|
||||
|
||||
```yaml
|
||||
deploy_staging:
|
||||
stage: deploy
|
||||
script:
|
||||
- deploy --env staging
|
||||
environment:
|
||||
name: staging
|
||||
url: https://staging.example.com
|
||||
on_stop: stop_staging
|
||||
|
||||
stop_staging:
|
||||
stage: deploy
|
||||
script:
|
||||
- undeploy --env staging
|
||||
environment:
|
||||
name: staging
|
||||
action: stop
|
||||
when: manual
|
||||
```
|
||||
|
||||
## Docker Builds
|
||||
|
||||
```yaml
|
||||
build_image:
|
||||
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 $CI_REGISTRY
|
||||
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
```
|
||||
|
||||
## GitLab Runners
|
||||
|
||||
### Install Runner
|
||||
|
||||
```bash
|
||||
# Download and install
|
||||
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
|
||||
sudo apt install gitlab-runner
|
||||
|
||||
# Register runner
|
||||
sudo gitlab-runner register \
|
||||
--url https://gitlab.com/ \
|
||||
--registration-token TOKEN \
|
||||
--executor docker \
|
||||
--docker-image alpine:latest
|
||||
```
|
||||
|
||||
### Runner Configuration
|
||||
|
||||
```toml
|
||||
# /etc/gitlab-runner/config.toml
|
||||
[[runners]]
|
||||
name = "docker-runner"
|
||||
url = "https://gitlab.com/"
|
||||
token = "TOKEN"
|
||||
executor = "docker"
|
||||
[runners.docker]
|
||||
image = "alpine:latest"
|
||||
privileged = true
|
||||
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
|
||||
```
|
||||
|
||||
### Runner Tags
|
||||
|
||||
```yaml
|
||||
build:
|
||||
tags:
|
||||
- docker
|
||||
- linux
|
||||
script:
|
||||
- make build
|
||||
```
|
||||
|
||||
## CI/CD Variables
|
||||
|
||||
### Protected Variables
|
||||
|
||||
Define in Settings > CI/CD > Variables:
|
||||
- `AWS_ACCESS_KEY_ID` (protected, masked)
|
||||
- `AWS_SECRET_ACCESS_KEY` (protected, masked)
|
||||
|
||||
### Using Variables
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
script:
|
||||
- aws s3 sync dist/ s3://$S3_BUCKET
|
||||
variables:
|
||||
AWS_DEFAULT_REGION: us-east-1
|
||||
```
|
||||
|
||||
## Include and Extend
|
||||
|
||||
### Include Templates
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- template: Security/SAST.gitlab-ci.yml
|
||||
- project: 'group/shared-ci'
|
||||
file: '/templates/deploy.yml'
|
||||
- local: '/ci/jobs.yml'
|
||||
```
|
||||
|
||||
### Extend Jobs
|
||||
|
||||
```yaml
|
||||
.base_job:
|
||||
image: node:20
|
||||
before_script:
|
||||
- npm ci
|
||||
|
||||
build:
|
||||
extends: .base_job
|
||||
script:
|
||||
- npm run build
|
||||
|
||||
test:
|
||||
extends: .base_job
|
||||
script:
|
||||
- npm test
|
||||
```
|
||||
|
||||
## Multi-Project Pipelines
|
||||
|
||||
```yaml
|
||||
trigger_downstream:
|
||||
stage: deploy
|
||||
trigger:
|
||||
project: group/downstream-project
|
||||
branch: main
|
||||
strategy: depend
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Pipeline Stuck
|
||||
**Problem**: Jobs stay pending
|
||||
**Solution**: Check runner availability and tags matching
|
||||
|
||||
### Issue: Docker-in-Docker Fails
|
||||
**Problem**: Cannot connect to Docker daemon
|
||||
**Solution**: Use `docker:dind` service with proper TLS configuration
|
||||
|
||||
### Issue: Cache Not Working
|
||||
**Problem**: Cache misses between jobs
|
||||
**Solution**: Verify cache key and ensure runners share distributed cache
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use `rules` instead of `only/except` for complex conditions
|
||||
- Leverage GitLab's built-in security scanning templates
|
||||
- Use job dependencies to optimize pipeline speed
|
||||
- Implement review apps for merge requests
|
||||
- Cache dependencies aggressively
|
||||
- Use artifacts for passing data between stages
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [github-actions](../github-actions/) - GitHub CI/CD alternative
|
||||
- [argocd-gitops](../../orchestration/argocd-gitops/) - GitOps deployments
|
||||
- [container-registries](../../containers/container-registries/) - Registry management
|
||||
@@ -0,0 +1,113 @@
|
||||
# GitLab CI Pipeline Patterns
|
||||
|
||||
## Parent-Child Pipelines
|
||||
|
||||
```yaml
|
||||
# Parent pipeline
|
||||
stages:
|
||||
- triggers
|
||||
|
||||
trigger-services:
|
||||
stage: triggers
|
||||
trigger:
|
||||
include:
|
||||
- local: services/api/.gitlab-ci.yml
|
||||
- local: services/web/.gitlab-ci.yml
|
||||
strategy: depend
|
||||
```
|
||||
|
||||
## DAG (Directed Acyclic Graph)
|
||||
|
||||
```yaml
|
||||
build:
|
||||
stage: build
|
||||
script: make build
|
||||
|
||||
test-unit:
|
||||
stage: test
|
||||
needs: [build]
|
||||
script: make test-unit
|
||||
|
||||
test-integration:
|
||||
stage: test
|
||||
needs: [build]
|
||||
script: make test-integration
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
needs: [test-unit, test-integration]
|
||||
script: make deploy
|
||||
```
|
||||
|
||||
## Dynamic Child Pipelines
|
||||
|
||||
```yaml
|
||||
generate-config:
|
||||
stage: prepare
|
||||
script:
|
||||
- generate-pipeline.sh > child-pipeline.yml
|
||||
artifacts:
|
||||
paths:
|
||||
- child-pipeline.yml
|
||||
|
||||
trigger-child:
|
||||
stage: trigger
|
||||
trigger:
|
||||
include:
|
||||
- artifact: child-pipeline.yml
|
||||
job: generate-config
|
||||
```
|
||||
|
||||
## Multi-Project Pipelines
|
||||
|
||||
```yaml
|
||||
deploy-downstream:
|
||||
trigger:
|
||||
project: group/downstream-project
|
||||
branch: main
|
||||
strategy: depend
|
||||
variables:
|
||||
UPSTREAM_VERSION: $CI_COMMIT_SHA
|
||||
```
|
||||
|
||||
## Rules and Conditions
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
when: manual
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: on_success
|
||||
- when: never
|
||||
```
|
||||
|
||||
## Caching Strategies
|
||||
|
||||
```yaml
|
||||
default:
|
||||
cache:
|
||||
key:
|
||||
files:
|
||||
- package-lock.json
|
||||
paths:
|
||||
- node_modules/
|
||||
policy: pull-push
|
||||
|
||||
test:
|
||||
cache:
|
||||
policy: pull # Only read from cache
|
||||
```
|
||||
|
||||
## Services
|
||||
|
||||
```yaml
|
||||
test:
|
||||
services:
|
||||
- name: postgres:15
|
||||
alias: db
|
||||
- name: redis:7
|
||||
variables:
|
||||
POSTGRES_DB: test
|
||||
DATABASE_URL: postgres://postgres@db/test
|
||||
```
|
||||
@@ -0,0 +1,437 @@
|
||||
---
|
||||
name: jenkins
|
||||
description: Create and manage Jenkins CI/CD pipelines, configure agents, manage plugins, and automate builds. Use when working with Jenkins servers, creating Jenkinsfiles, or setting up build automation for enterprise environments.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Jenkins
|
||||
|
||||
Build, test, and deploy applications using Jenkins, the leading open-source automation server.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Setting up Jenkins pipelines (declarative or scripted)
|
||||
- Configuring Jenkins agents and executors
|
||||
- Managing Jenkins plugins and security
|
||||
- Creating shared libraries for pipeline reuse
|
||||
- Integrating Jenkins with external tools
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Jenkins server (2.x or later)
|
||||
- Admin access to Jenkins
|
||||
- Java 11+ on Jenkins server
|
||||
- Basic Groovy understanding for pipelines
|
||||
|
||||
## Declarative Pipeline
|
||||
|
||||
Create `Jenkinsfile` in repository root:
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
DOCKER_REGISTRY = 'registry.example.com'
|
||||
APP_NAME = 'myapp'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'npm ci'
|
||||
sh 'npm run build'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'npm test'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit 'test-results/*.xml'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
sh './deploy.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
failure {
|
||||
mail to: 'team@example.com',
|
||||
subject: "Pipeline Failed: ${env.JOB_NAME}",
|
||||
body: "Check console output at ${env.BUILD_URL}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Agent Configuration
|
||||
|
||||
### Docker Agent
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
image 'node:20'
|
||||
args '-v /tmp:/tmp'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'npm ci && npm run build'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Kubernetes Agent
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent {
|
||||
kubernetes {
|
||||
yaml '''
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
spec:
|
||||
containers:
|
||||
- name: node
|
||||
image: node:20
|
||||
command:
|
||||
- sleep
|
||||
args:
|
||||
- infinity
|
||||
- name: docker
|
||||
image: docker:24-dind
|
||||
securityContext:
|
||||
privileged: true
|
||||
'''
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
container('node') {
|
||||
sh 'npm ci && npm run build'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Labeled Agents
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent { label 'linux && docker' }
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'make build'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
parameters {
|
||||
string(name: 'BRANCH', defaultValue: 'main', description: 'Branch to build')
|
||||
choice(name: 'ENVIRONMENT', choices: ['dev', 'staging', 'prod'], description: 'Target environment')
|
||||
booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Run tests?')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Deploy') {
|
||||
when {
|
||||
expression { params.ENVIRONMENT == 'prod' }
|
||||
}
|
||||
steps {
|
||||
sh "deploy.sh ${params.ENVIRONMENT}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
### Using Credentials
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
AWS_CREDS = credentials('aws-credentials')
|
||||
DOCKER_CREDS = credentials('docker-hub')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Deploy') {
|
||||
steps {
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'github-token',
|
||||
usernameVariable: 'GH_USER',
|
||||
passwordVariable: 'GH_TOKEN'
|
||||
)
|
||||
]) {
|
||||
sh 'git push https://${GH_USER}:${GH_TOKEN}@github.com/repo.git'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Parallel Stages
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Tests') {
|
||||
parallel {
|
||||
stage('Unit Tests') {
|
||||
steps {
|
||||
sh 'npm run test:unit'
|
||||
}
|
||||
}
|
||||
stage('Integration Tests') {
|
||||
steps {
|
||||
sh 'npm run test:integration'
|
||||
}
|
||||
}
|
||||
stage('E2E Tests') {
|
||||
steps {
|
||||
sh 'npm run test:e2e'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Shared Libraries
|
||||
|
||||
### Library Structure
|
||||
|
||||
```
|
||||
vars/
|
||||
├── buildApp.groovy
|
||||
├── deployApp.groovy
|
||||
└── notifySlack.groovy
|
||||
src/
|
||||
└── com/example/
|
||||
└── Pipeline.groovy
|
||||
resources/
|
||||
└── templates/
|
||||
└── deployment.yaml
|
||||
```
|
||||
|
||||
### Define Shared Step
|
||||
|
||||
```groovy
|
||||
// vars/buildApp.groovy
|
||||
def call(Map config = [:]) {
|
||||
def nodeVersion = config.nodeVersion ?: '20'
|
||||
|
||||
docker.image("node:${nodeVersion}").inside {
|
||||
sh 'npm ci'
|
||||
sh 'npm run build'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use Shared Library
|
||||
|
||||
```groovy
|
||||
@Library('my-shared-library') _
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
buildApp(nodeVersion: '20')
|
||||
}
|
||||
}
|
||||
stage('Deploy') {
|
||||
steps {
|
||||
deployApp(environment: 'staging')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
failure {
|
||||
notifySlack(channel: '#builds', status: 'FAILED')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Scripted Pipeline
|
||||
|
||||
```groovy
|
||||
node('linux') {
|
||||
try {
|
||||
stage('Checkout') {
|
||||
checkout scm
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
docker.image('node:20').inside {
|
||||
sh 'npm ci'
|
||||
sh 'npm run build'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
sh 'npm test'
|
||||
}
|
||||
|
||||
if (env.BRANCH_NAME == 'main') {
|
||||
stage('Deploy') {
|
||||
sh './deploy.sh'
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
throw e
|
||||
} finally {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin Management
|
||||
|
||||
### Essential Plugins
|
||||
|
||||
```groovy
|
||||
// Install via Jenkins CLI or init.groovy.d
|
||||
def plugins = [
|
||||
'workflow-aggregator', // Pipeline
|
||||
'git', // Git integration
|
||||
'docker-workflow', // Docker Pipeline
|
||||
'kubernetes', // Kubernetes agent
|
||||
'credentials-binding', // Credentials
|
||||
'blueocean', // Blue Ocean UI
|
||||
'job-dsl', // Job DSL
|
||||
'configuration-as-code' // JCasC
|
||||
]
|
||||
```
|
||||
|
||||
### Configuration as Code
|
||||
|
||||
```yaml
|
||||
# jenkins.yaml
|
||||
jenkins:
|
||||
systemMessage: "Jenkins configured via JCasC"
|
||||
numExecutors: 2
|
||||
|
||||
securityRealm:
|
||||
local:
|
||||
users:
|
||||
- id: admin
|
||||
password: ${ADMIN_PASSWORD}
|
||||
|
||||
authorizationStrategy:
|
||||
globalMatrix:
|
||||
permissions:
|
||||
- "Overall/Administer:admin"
|
||||
- "Overall/Read:authenticated"
|
||||
|
||||
credentials:
|
||||
system:
|
||||
domainCredentials:
|
||||
- credentials:
|
||||
- usernamePassword:
|
||||
id: "docker-hub"
|
||||
username: "user"
|
||||
password: ${DOCKER_PASSWORD}
|
||||
```
|
||||
|
||||
## Multibranch Pipeline
|
||||
|
||||
```groovy
|
||||
// Automatically discovers branches with Jenkinsfile
|
||||
// Configure in Jenkins UI: New Item > Multibranch Pipeline
|
||||
|
||||
// Branch-specific behavior in Jenkinsfile
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Deploy') {
|
||||
when {
|
||||
anyOf {
|
||||
branch 'main'
|
||||
branch 'release/*'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh './deploy.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Pipeline Syntax Errors
|
||||
**Problem**: Jenkinsfile fails to parse
|
||||
**Solution**: Use Pipeline Syntax generator in Jenkins UI, validate with `jenkins-cli`
|
||||
|
||||
### Issue: Agent Not Connecting
|
||||
**Problem**: Build agents disconnect
|
||||
**Solution**: Check agent logs, verify network connectivity, increase timeout settings
|
||||
|
||||
### Issue: Out of Memory
|
||||
**Problem**: Jenkins crashes or builds fail with OOM
|
||||
**Solution**: Increase heap size in `JAVA_OPTS`, clean up old builds
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use declarative pipelines for most use cases
|
||||
- Implement shared libraries for reusable code
|
||||
- Store Jenkinsfile in source control
|
||||
- Use credentials plugin for secrets management
|
||||
- Implement proper cleanup in post blocks
|
||||
- Configure build retention policies
|
||||
- Use Blue Ocean for modern UI experience
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [github-actions](../github-actions/) - GitHub native CI/CD
|
||||
- [kubernetes-ops](../../orchestration/kubernetes-ops/) - K8s deployment target
|
||||
- [docker-management](../../containers/docker-management/) - Container builds
|
||||
@@ -0,0 +1,128 @@
|
||||
# Jenkins Pipeline Syntax Reference
|
||||
|
||||
## Declarative Pipeline
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
options {
|
||||
timeout(time: 1, unit: 'HOURS')
|
||||
disableConcurrentBuilds()
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
}
|
||||
|
||||
environment {
|
||||
DEPLOY_ENV = 'production'
|
||||
CREDS = credentials('my-credentials')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'make build'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
parallel {
|
||||
stage('Unit Tests') {
|
||||
steps {
|
||||
sh 'make test-unit'
|
||||
}
|
||||
}
|
||||
stage('Integration Tests') {
|
||||
steps {
|
||||
sh 'make test-integration'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
sh 'make deploy'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
junit 'reports/**/*.xml'
|
||||
cleanWs()
|
||||
}
|
||||
success {
|
||||
slackSend color: 'good', message: 'Build succeeded'
|
||||
}
|
||||
failure {
|
||||
slackSend color: 'danger', message: 'Build failed'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Scripted Pipeline
|
||||
|
||||
```groovy
|
||||
node('linux') {
|
||||
try {
|
||||
stage('Checkout') {
|
||||
checkout scm
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
sh 'make build'
|
||||
}
|
||||
|
||||
if (env.BRANCH_NAME == 'main') {
|
||||
stage('Deploy') {
|
||||
sh 'make deploy'
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
throw e
|
||||
} finally {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Shared Libraries
|
||||
|
||||
```groovy
|
||||
// vars/buildPipeline.groovy
|
||||
def call(Map config) {
|
||||
pipeline {
|
||||
agent any
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh config.buildCommand ?: 'make build'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jenkinsfile
|
||||
@Library('my-shared-library') _
|
||||
buildPipeline(buildCommand: 'npm run build')
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
```groovy
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'docker-hub',
|
||||
usernameVariable: 'DOCKER_USER',
|
||||
passwordVariable: 'DOCKER_PASS'
|
||||
)
|
||||
]) {
|
||||
sh 'docker login -u $DOCKER_USER -p $DOCKER_PASS'
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user