Expert-level Harness template types, runtime inputs, expression language, pipeline patterns (CI/CD, GitOps, Canary, Blue-Green), versioning, and step configurations
npx claudepluginhub markus41/claude --plugin claude-code-templatingThis skill is limited to using the following tools:
Expert knowledge of Harness template types, expression language, pipeline patterns, and deployment strategies.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Expert knowledge of Harness template types, expression language, pipeline patterns, and deployment strategies.
Purpose: Reusable step configurations across pipelines
Types:
Template Structure:
template:
name: Deploy to Kubernetes
type: Step
spec:
type: K8sDeploy
spec:
service: <+input>
environment: <+input>
kubernetesCluster: <+input>
namespace: <+input>
releaseName: <+input>
timeout: <+input.deployment_timeout>
skipDryRun: false
allowNoFilesFound: false
delegateSelectors:
- <+input.delegate_selector>
Runtime Inputs (Required):
templateInputs:
spec:
service:
serviceRef: <+input.service_name>
environment:
environmentRef: <+input.environment_name>
kubernetesCluster:
clusterId: <+input.cluster_id>
namespace: <+input.k8s_namespace>
releaseName: <+input.release_name>
Purpose: Reusable stage definitions with multiple steps
Template Structure:
template:
name: Deploy Stage Template
type: Stage
spec:
type: Deployment
spec:
service:
serviceRef: <+input.service_ref>
infrastructure:
infrastructureDefinition:
type: <+input.infra_type> # Kubernetes, AWS, GCP, etc.
spec: <+input.infra_spec>
execution:
steps:
- step:
name: Deploy
identifier: deploy
type: K8sDeploy
spec:
service: <+input.service_ref>
environment: <+input.environment_ref>
- step:
name: Verify
identifier: verify
type: ShellScript
spec:
script: <+input.verify_script>
Purpose: Full pipeline definitions with approval gates, notifications, conditions
Template Structure:
template:
name: Complete CI/CD Pipeline
type: Pipeline
spec:
stages:
- stage:
name: Build
identifier: build
type: CI
spec:
codebase:
repoName: <+input.repo_name>
branch: <+input.branch>
build:
type: Docker
spec:
dockerfile: Dockerfile
registryConnector: <+input.registry_connector>
- stage:
name: Deploy Dev
identifier: deploy_dev
type: Deployment
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: dev
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.dev_cluster_id>
- stage:
name: Approval
identifier: approval
type: Approval
spec:
approvalStepType: ShellScript
script: echo "Deploying to production..."
- stage:
name: Deploy Prod
identifier: deploy_prod
type: Deployment
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: prod
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.prod_cluster_id>
<+input>) Syntaxspec:
service:
serviceRef: <+input> # Required, user must provide
timeout: <+input.deployment_timeout> # Optional with variable name
replicas: <+input | default(3)> # With default value
String Input:
image: <+input>
service: <+input.service_name>
Number Input:
timeout: <+input.timeout_minutes>
replicas: <+input | default(3)>
Boolean Input:
skip_tests: <+input | default(false)>
enable_monitoring: <+input>
List/Array Input:
environments: <+input.env_list>
delegate_selectors: <+input.selectors>
Object Input:
infrastructure: <+input.infra_spec>
# Only required if another input is true
{{#if use_custom_image}}
image: <+input.custom_image>
{{/if}}
# Conditional with expression
<+if>
conditions:
- key: environment
operator: equals
value: production
then: <+input.prod_cluster>
else: <+input.dev_cluster>
</+if>
# Access pipeline metadata
<+pipeline.name> # Pipeline name
<+pipeline.identifier> # Pipeline identifier
<+pipeline.executionId> # Execution ID
<+pipeline.triggeredBy> # Who triggered it
<+pipeline.startTs> # Start timestamp
<+pipeline.sequenceNumber> # Execution sequence
# Access stage metadata
<+stage.name> # Stage name
<+stage.identifier> # Stage identifier
<+stage.status> # Stage status (Success, Failed, etc.)
<+stage.type> # Stage type (CI, Deployment, etc.)
# Stage variables
<+stage.variables.VARIABLE_NAME> # Stage variable
<+stageArtifacts.IMAGE_ID> # Output artifacts
# Access step outputs
<+steps.STEP_ID.output.outputKey> # Step output variable
<+steps.build_docker.output.image> # Docker image from build step
<+steps.deploy.status> # Step execution status
# Example
<+steps.deploy.deploymentStatuses> # Deployment status details
<+env.JIRA_URL> # Environment variable
<+env.DOCKER_REGISTRY> # From infrastructure
# Example in script
- step:
type: ShellScript
spec:
script: |
echo "Registry: <+env.DOCKER_REGISTRY>"
docker push <+env.DOCKER_REGISTRY>/myapp
# Retrieve secrets
<+secrets.getValue("my_secret")> # Simple secret
<+secrets.getValue("vault://prod/db_pwd")> # Vault path
# Example
- step:
type: ShellScript
spec:
environmentVariables:
DB_PASSWORD: <+secrets.getValue("database_password")>
# Artifacts from previous stages
<+artifact.image> # Primary artifact
<+artifact.imageTag> # Image tag
<+artifacts.COLLECTOR.IMAGE_ID> # Named artifact
# Example in deploy
- step:
type: K8sDeploy
spec:
image: <+artifact.image>:<+artifact.imageTag>
service: <+input.service_ref>
Description: Standard continuous integration and deployment
Flow: Build → Test → Deploy Dev → Approval → Deploy Prod
template:
name: Standard CI/CD
type: Pipeline
spec:
stages:
# Stage 1: Build
- stage:
name: Build
identifier: build
type: CI
spec:
codebase:
repoName: <+input.repo_name>
branch: <+input.branch>
build:
type: Docker
spec:
dockerfile: Dockerfile
registryConnector: <+input.docker_connector>
imageName: <+input.image_name>
imageTag: <+artifact.imageTag>
# Stage 2: Test
- stage:
name: Test
identifier: test
type: CI
depends:
on:
- build
spec:
build:
type: Container
spec:
image: <+steps.build.output.image>
command: npm test -- --coverage
# Stage 3: Deploy Dev
- stage:
name: Deploy Dev
identifier: deploy_dev
type: Deployment
depends:
on:
- test
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: dev
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.dev_cluster>
execution:
steps:
- step:
type: K8sDeploy
spec:
service: <+input.service_ref>
image: <+artifact.image>
# Stage 4: Manual Approval
- stage:
name: Approval for Production
identifier: approval
type: Approval
depends:
on:
- deploy_dev
spec:
approvalStepType: Manual
approvers:
- <+input.approver_group>
# Stage 5: Deploy Production
- stage:
name: Deploy Production
identifier: deploy_prod
type: Deployment
depends:
on:
- approval
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: prod
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.prod_cluster>
execution:
steps:
- step:
type: K8sDeploy
spec:
service: <+input.service_ref>
image: <+artifact.image>
Description: GitOps pattern using Argo CD for deployments
Flow: Build → Push Manifest → Trigger ArgoCD → Verify
template:
name: GitOps CI/CD Pipeline
type: Pipeline
spec:
stages:
# Stage 1: Build Docker Image
- stage:
name: Build
identifier: build
type: CI
spec:
codebase:
repoName: <+input.repo_name>
branch: <+input.branch>
build:
type: Docker
spec:
dockerfile: Dockerfile
registryConnector: <+input.docker_connector>
imageName: <+input.image_name>
# Stage 2: Update Manifest Repository
- stage:
name: Update Manifests
identifier: update_manifests
type: CI
depends:
on:
- build
spec:
steps:
- step:
type: Run
spec:
container:
image: ubuntu:22.04
shell: Bash
script: |
git clone <+input.manifest_repo> manifests
cd manifests
sed -i "s|IMAGE_TAG|<+artifact.imageTag>|g" k8s/deployment.yaml
git add k8s/deployment.yaml
git commit -m "Update image to <+artifact.imageTag>"
git push origin main
# Stage 3: Trigger ArgoCD Sync
- stage:
name: Deploy via ArgoCD
identifier: deploy_argocd
type: Deployment
depends:
on:
- update_manifests
spec:
steps:
- step:
type: Http
spec:
url: <+input.argocd_api_url>/api/v1/applications/<+input.app_name>/sync
method: Post
headers:
Authorization: Bearer <+secrets.getValue("argocd_token")>
requestBody: |
{
"syncPolicy": {
"syncStrategy": {
"argo": {}
}
}
}
# Stage 4: Verify Deployment
- stage:
name: Verify
identifier: verify
type: Deployment
depends:
on:
- deploy_argocd
spec:
steps:
- step:
type: ShellScript
spec:
script: |
kubectl rollout status deployment/<+input.app_name> \
-n <+input.namespace> \
--timeout=5m
Description: Gradual traffic shift with automated verification
Flow: Deploy Canary (5%) → Verify → Increment Traffic (25%) → Verify → Full Deploy
template:
name: Canary Deployment Pattern
type: Pipeline
spec:
stages:
# Stage 1: Deploy Canary (5% traffic)
- stage:
name: Deploy Canary
identifier: deploy_canary
type: Deployment
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: prod
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.prod_cluster>
execution:
steps:
- step:
type: K8sDeploy
spec:
canaryStrategy:
enabled: true
canaryPercentage: 5
service: <+input.service_ref>
image: <+artifact.image>
# Stage 2: Verify Canary Metrics
- stage:
name: Verify Canary
identifier: verify_canary
type: Deployment
depends:
on:
- deploy_canary
spec:
steps:
- step:
type: ShellScript
spec:
script: |
# Check error rate, latency, etc.
kubectl logs -l version=canary -n <+input.namespace> \
--since=10m | grep ERROR | wc -l > /tmp/errors
ERRORS=$(cat /tmp/errors)
if [ $ERRORS -gt <+input.error_threshold> ]; then
exit 1
fi
# Stage 3: Increment Traffic (25%)
- stage:
name: Increment Traffic
identifier: increment_traffic
type: Deployment
depends:
on:
- verify_canary
spec:
steps:
- step:
type: ShellScript
spec:
script: |
kubectl patch vs <+input.service_ref> -n <+input.namespace> \
-p '{"spec":{"hosts":[{"name":"*","http":[{"match":[{"uri":{"regex":".*"}}],"route":[{"destination":{"host":"<+input.service_ref>","subset":"canary"},"weight":25}]}]}]}}'
# Stage 4: Verify Again
- stage:
name: Verify Increment
identifier: verify_increment
type: Deployment
depends:
on:
- increment_traffic
spec:
steps:
- step:
type: ShellScript
spec:
script: |
sleep 300 # Wait 5 minutes
# Same verification logic
# Stage 5: Full Deployment
- stage:
name: Deploy Full
identifier: deploy_full
type: Deployment
depends:
on:
- verify_increment
spec:
steps:
- step:
type: K8sDeploy
spec:
service: <+input.service_ref>
image: <+artifact.image>
canaryStrategy:
enabled: true
canaryPercentage: 100
Description: Two identical production environments with instant switching
Flow: Build → Deploy to Green (inactive) → Verify → Switch Traffic → Cleanup Blue
template:
name: Blue-Green Deployment Pattern
type: Pipeline
spec:
variables:
- name: active_color
type: String
default: blue
- name: inactive_color
type: String
default: green
stages:
# Stage 1: Deploy to Inactive Environment
- stage:
name: Deploy to Inactive
identifier: deploy_inactive
type: Deployment
spec:
service:
serviceRef: <+input.service_ref>
environment:
environmentRef: <+pipeline.variables.inactive_color>
infrastructure:
infrastructureDefinition:
type: Kubernetes
spec:
clusterId: <+input.prod_cluster>
execution:
steps:
- step:
type: K8sDeploy
spec:
service: <+input.service_ref>
image: <+artifact.image>
# Stage 2: Run Smoke Tests
- stage:
name: Smoke Tests
identifier: smoke_tests
type: CI
depends:
on:
- deploy_inactive
spec:
steps:
- step:
type: Run
spec:
container:
image: postman/newman
shell: Bash
script: |
newman run tests/smoke-collection.json \
--environment env-<+pipeline.variables.inactive_color>.json \
--reporters cli,json
# Stage 3: Manual Approval for Switch
- stage:
name: Approve Traffic Switch
identifier: approve_switch
type: Approval
depends:
on:
- smoke_tests
spec:
approvalStepType: Manual
approvers:
- <+input.approver_group>
# Stage 4: Switch Traffic
- stage:
name: Switch Traffic
identifier: switch_traffic
type: Deployment
depends:
on:
- approve_switch
spec:
steps:
- step:
type: ShellScript
spec:
script: |
# Switch load balancer/service to point to inactive environment
kubectl patch service <+input.service_ref> \
-n production \
-p '{"spec":{"selector":{"version":"<+pipeline.variables.inactive_color>"}}}'
# Stage 5: Verify Active Environment
- stage:
name: Verify Active
identifier: verify_active
type: Deployment
depends:
on:
- switch_traffic
spec:
steps:
- step:
type: ShellScript
spec:
script: |
for i in {1..30}; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" <+input.prod_url>/health)
if [ $STATUS -eq 200 ]; then
echo "Health check passed"
exit 0
fi
sleep 10
done
exit 1
# Stage 6: Cleanup Old Environment
- stage:
name: Cleanup
identifier: cleanup
type: Deployment
depends:
on:
- verify_active
spec:
steps:
- step:
type: ShellScript
spec:
script: |
kubectl scale deployment <+input.service_ref>-<+pipeline.variables.active_color> \
-n production \
--replicas=0
MAJOR.MINOR.PATCH
- MAJOR: Breaking changes (input names change, outputs change)
- MINOR: New optional inputs or non-breaking changes
- PATCH: Bug fixes, documentation updates
template:
name: Deploy Service
identifier: deploy_service
versionLabel: "2.1.0"
spec:
# Template specification
# Always use specific version in production
stages:
- stage:
template:
templateRef: deploy_service
versionLabel: "2.1.0" # Explicit version
templateInputs:
spec:
service: <+input.service_ref>
## Version 2.1.0 (2024-01-15)
- Added: Support for custom health checks
- Added: Optional monitoring setup
- Improved: Error messages for common issues
- Fixed: Timeout handling in K8s deployments
## Version 2.0.0 (2024-01-01) - BREAKING
- Changed: Input name from 'cluster' to 'clusterId'
- Changed: Stage type from 'Deploy' to 'Deployment'
- Removed: Legacy inline script support
## Version 1.0.0 (2023-12-01)
- Initial release
- step:
name: Deploy to Kubernetes
identifier: k8s_deploy
type: K8sDeploy
spec:
service: <+input.service_ref>
environment: <+input.environment_ref>
kubernetesCluster:
clusterId: <+input.cluster_id>
namespace: <+input.namespace>
releaseName: <+input.release_name>
timeout: 10m
skipDryRun: false
allowNoFilesFound: false
delegateSelectors:
- <+input.delegate_selector>
- step:
name: Run Docker Step
identifier: docker_step
type: Run
spec:
container:
image: <+input.image>
shell: Bash
runAsUser: <+input.user>
script: |
#!/bin/bash
set -e
echo "Running test suite..."
npm test -- --coverage
echo "Test passed!"
envVariables:
TEST_ENV: <+input.environment>
API_URL: <+env.API_URL>
outputVariables:
- name: test_result
value: $(cat test-results.json)
- step:
name: Notify Slack
identifier: notify_slack
type: Http
spec:
url: <+input.slack_webhook>
method: Post
headers:
Content-Type: application/json
requestBody: |
{
"text": "Deployment to <+input.environment> completed!",
"attachments": [
{
"text": "Version: <+artifact.imageTag>"
}
]
}
- step:
name: Manual Approval
identifier: approval
type: Approval
spec:
approvalMessage: Deploy to production?
approvers:
- <+input.approver_group>
approvalTimeout: 1d
autoRejectIfNoActivity: true
isAutoRejectAfterOverride: true