Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
circleci【部署与运维】Use this skill when the user says 'CircleCI', 'circleci config', 'orb', 'workflows', 'jobs', 'steps', 'executors', 'Docker executor', 'machine executor', 'CircleCI runner', 'pipeline', 'context', 'store_artifacts', 'save_cache', 'restore_cache', 'parallelism', 'circleci local', 'SSH debug'. Covers: CircleCI configuration (config.yml), executors, jobs…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Define CI/CD pipelines using CircleCI configuration with workflows, jobs, orbs, caching strategies, and parallel execution for fast, reliable builds.
| Executor | Speed | Best For | Limitations |
|---|---|---|---|
| Docker | Fast (<30s start) | Standard builds | Container-only, limited to Docker |
| Machine | Slow (~60s start) | Docker-in-Docker, full VM | More expensive, fewer concurrent jobs |
| macOS | Slow | iOS/macOS builds | Apple-only, limited parallelism |
| Windows | Moderate | .NET, Windows-specific | Limited images, slower startup |
| GPU (Linux) | Fast | ML/DL training | Expensive, limited availability |
| Strategy | Save Key | Restore Keys | Use Case |
|---|---|---|---|
| Lockfile hash | v1-deps-{{ checksum "package-lock.json" }} | v1-deps- | Node.js, Go, Rust |
| Multiple deps | v1-deps-{{ arch }}-{{ .Branch }}-{{ checksum "..." }} | v1-deps-{{ arch }}- | Cross-platform, multiple deps |
| Fallback chain | v1-{{ .Branch }}-{{ .Revision }} | v1-{{ .Branch }}-, v1-master- | Caching across branches |
| No-cache clean | Skip cache | None | Clean builds after dependency changes |
| Method | Command | Best For |
|---|---|---|
| Timing-based | circleci tests split --split-by=timings | Uneven tests, rebalance over runs |
| Name-based | circleci tests split --split-by=name | Equal test distribution |
| File-size | circleci tests split --split-by=filesize | Integration tests with different sizes |
| Custom | Manual glob + assignment | Specific test grouping requirements |
| Trigger Type | When to Use | Configuration |
|---|---|---|
| Push to branch | Default CI | on: [push] |
| Pull request | Review validation | on: [pull_request] |
| Schedule | Nightly, weekly, monthly | triggers: - schedule: {cron: "0 2 * * *"} |
| Manual approval | Production deploy | type: approval in workflow |
| Pipeline parameter | Conditional triggers | parameters: [deploy: {type: boolean}] |
config.yml with default Docker executor → checkout → restore_cache → install deps → run tests → save_cache → store_artifacts → workflow with lint-test-deploy stages.
# .circleci/config.yml
version: 2.1
orbs:
node: circleci/node@5.1.0
aws-cli: circleci/aws-cli@3.1.4
slack: circleci/slack@4.12.5
parameters:
deploy-prod:
type: boolean
default: false
executors:
node-executor:
docker:
- image: cimg/node:22.0
resource_class: medium
machine-executor:
machine:
image: ubuntu-2204:current
resource_class: medium
commands:
setup-dependencies:
steps:
- node/install-packages:
pkg-manager: npm
- run:
name: Verify dependencies
command: |
npm audit --audit-level=high
npx license-checker --summary
build-app:
steps:
- run: npm run build
- persist_to_workspace:
root: .
paths:
- dist/
- node_modules/
jobs:
lint:
executor: node-executor
steps:
- checkout
- setup-dependencies
- run: npm run lint
test:
executor: node-executor
parallelism: 4
steps:
- checkout
- setup-dependencies
- run:
name: Run tests with splitting
command: |
circleci tests glob "tests/**/*.test.ts" | \
circleci tests run --command="xargs npx jest --ci --runInBand" \
--split-by=timings
- store_test_results:
path: test-results/
- store_artifacts:
path: test-results/
destination: test-reports
build:
executor: machine-executor
steps:
- checkout
- setup-dependencies
- build-app
- run:
name: Build Docker image
command: |
docker build -t myapp:$CIRCLE_SHA1 .
echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin
docker push myapp:$CIRCLE_SHA1
- store_artifacts:
path: dist/
destination: build-output
deploy-staging:
executor: machine-executor
steps:
- attach_workspace:
at: .
- aws-cli/setup:
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
region: us-east-1
- run:
name: Deploy to staging
command: |
aws ecs update-service --cluster staging \
--service myapp --force-new-deployment
deploy-production:
executor: machine-executor
steps:
- slack/notify:
event: pending
message: "Production deploy starting..."
- deploy-staging
- slack/notify:
event: success
message: "Production deploy completed successfully"
- slack/notify:
event: fail
message: "Production deploy FAILED"
security-scan:
executor: node-executor
steps:
- checkout
- node/install-packages
- run: npm audit --audit-level=high
- run:
name: Snyk security scan
command: |
curl -sL https://snyk.io/cli/install | bash
snyk test --severity-threshold=high
nightly-e2e:
machine: true
steps:
- checkout
- run: npm ci
- run: npm run test:e2e
- store_artifacts:
path: cypress/videos/
workflows:
version: 2
ci-pipeline:
unless: << pipeline.parameters.deploy-prod >>
jobs:
- lint
- test:
requires: [lint]
- build:
requires: [test]
- security-scan:
requires: [lint]
- deploy-staging:
requires: [build, security-scan]
filters:
branches:
only: main
- hold-production:
type: approval
requires: [deploy-staging]
- deploy-production:
requires: [hold-production]
filters:
branches:
only: main
nightly-tests:
triggers:
- schedule:
cron: "0 3 * * *"
filters:
branches:
only: main
jobs:
- test
- nightly-e2e
production-deploy:
when: << pipeline.parameters.deploy-prod >>
jobs:
- deploy-production
# Trigger with API:
# curl -X POST https://circleci.com/api/v2/project/gh/org/repo/pipeline \
# -H "Circle-Token: $TOKEN" \
# -d '{"parameters": {"deploy-prod": true}}'
# In config.yml, use pipeline parameters
parameters:
deploy-prod:
type: boolean
default: false
service-name:
type: string
default: "all"
workflows:
version: 2
deploy-service:
when: << pipeline.parameters.deploy-prod >>
jobs:
- deploy:
name: "deploy-<< pipeline.parameters.service-name >>"
# Matrix jobs
test-matrix:
parameters:
node-version:
type: string
executor:
docker:
- image: cimg/node:<< parameters.node-version >>
steps:
- checkout
- run: npm ci
- run: npm test
workflows:
test-all-versions:
jobs:
- test-matrix:
matrix:
parameters:
node-version: ["18.0", "20.0", "22.0"]
# .circleci/orbs/my-orb/orb.yml
version: 2.1
description: "Custom deployment orb"
commands:
deploy:
parameters:
environment:
type: enum
enum: ["dev", "staging", "prod"]
cluster:
type: string
steps:
- run:
name: Deploy to << parameters.environment >>
command: |
aws ecs update-service \
--cluster << parameters.cluster >> \
--service myapp-<< parameters.environment >> \
--force-new-deployment
- run:
name: Wait for deployment
command: |
aws ecs wait services-stable \
--cluster << parameters.cluster >> \
--services myapp-<< parameters.environment >>
canary-deploy:
parameters:
percent:
type: integer
default: 10
steps:
- run:
command: |
echo "Deploying to << parameters.percent >>% of traffic"
# Canary logic here
executors:
aws-executor:
docker:
- image: cimg/python:3.11
environment:
AWS_REGION: us-east-1
# Performance optimization
jobs:
test:
docker:
- image: cimg/node:22.0
resource_class: medium+ # 4 vCPU, 8GB RAM
parallelism: 8
steps:
- checkout
# Dependency caching
- 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
- ~/.npm
# Test with parallelization
- run: |
TESTFILES=$(circleci tests glob "tests/**/*.test.ts" | circleci tests split)
npx jest --ci --maxWorkers=2 $TESTFILES
- store_test_results:
path: test-results/
Using default medium for all jobs. Build and test jobs benefit from medium+ (faster) or arm.medium (cheaper for ARM builds).
Single huge config.yml. Split into reusable orbs, commands, and executors for composability.
Running all tests serially on one container. Use parallelism: N with circleci tests split for significant time reduction.
Reinstalling dependencies every build. Use save_cache/restore_cache with appropriate key patterns.
Putting environment variables in config.yml. Use CircleCI contexts and project environment variables.
circleci local execute --job test) for troubleshooting.cimg/base) for faster executor startup.Next: cicd-pipeline — general pipeline concepts beyond CircleCI.
version: 2.1
orbs:
node: circleci/node@5.1.0
commands:
restore-workspace:
steps:
- attach_workspace:
at: ~/project
jobs:
test-sharded:
executor: node/default
parallelism: 4
steps:
- checkout
- restore-workspace
- run: npm ci
- run:
command: |
TEST_FILES=$(circleci tests glob "tests/**/*.test.ts" | circleci tests split --split-by=timings)
npx jest --ci --runInBand $TEST_FILES
- store_test_results:
path: junit.xml
deploy:
executor: node/default
steps:
- checkout
- setup_remote_docker
- run: |
docker build -t $DOCKER_REGISTRY/app:$CIRCLE_SHA1 .
docker push $DOCKER_REGISTRY/app:$CIRCLE_SHA1
- run: |
ssh deploy@$HOST "kubectl set image deployment/app \
app=$DOCKER_REGISTRY/app:$CIRCLE_SHA1"
workflows:
version: 2
ci:
jobs:
- test-sharded
- deploy:
requires:
- test-sharded
filters:
branches:
only: main
#!/usr/bin/env bash
trigger_pipeline() {
local project_slug=$1
local branch=$2
curl -X POST \
"https://circleci.com/api/v2/project/${project_slug}/pipeline" \
-H "Circle-Token: ${CIRCLE_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"branch\": \"${branch}\",
\"parameters\": {
\"run_integration_tests\": true,
\"deploy_to_staging\": true
}
}"
}
medium+ for test, large for buildsmachine executor when docker executor suffices — increases setup timesetup_remote_docker on every job when one shared Docker context sufficessetup_remote_docker--split-by=timings for optimal test distributionsave_cache/restore_cache by lockfile checksum