Commit 2c6d94568a91
Changed files (8)
dots
.config
claude
skills
Tekton
dots/.config/claude/skills/Tekton/workflows/BestPractices.md
@@ -0,0 +1,590 @@
+# Best Practices Workflow
+
+Tekton best practices for security, performance, reliability, and maintainability.
+
+## When to Use
+
+- Optimizing Tekton pipelines
+- Implementing security best practices
+- Improving performance
+- Operating Tekton at scale
+- Troubleshooting common issues
+
+## Security Best Practices
+
+### Workspace-Based Authentication (2024 Recommendation)
+
+**DO: Use workspace-based authentication**
+```yaml
+workspaces:
+ - name: git-credentials
+ secret:
+ secretName: git-ssh-key
+```
+
+**DON'T: Rely only on built-in credential initialization**
+- Being phased out
+- All steps get access to all credentials
+- Credentials copied to disk
+- Security issues with different UIDs
+
+### ServiceAccount and RBAC
+
+**Create dedicated ServiceAccounts:**
+```yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: pipeline-sa
+secrets:
+ - name: docker-credentials
+ - name: git-credentials
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: pipeline-role
+rules:
+ - apiGroups: [""]
+ resources: ["pods", "services"]
+ verbs: ["get", "list"]
+ - apiGroups: ["apps"]
+ resources: ["deployments"]
+ verbs: ["get", "list", "update", "patch"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: pipeline-binding
+subjects:
+ - kind: ServiceAccount
+ name: pipeline-sa
+roleRef:
+ kind: Role
+ name: pipeline-role
+ apiGroup: rbac.authorization.k8s.io
+```
+
+**Principle of least privilege:**
+- Create separate ServiceAccounts for CI and CD
+- Grant only necessary permissions
+- Use Role instead of ClusterRole when possible
+- Regularly audit permissions
+
+### Pod Security
+
+```yaml
+spec:
+ steps:
+ - name: secure-step
+ image: alpine
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ capabilities:
+ drop:
+ - ALL
+```
+
+### Secrets Management
+
+**DO:**
+- Use Kubernetes Secrets or external secret managers (Vault, AWS Secrets Manager)
+- Mount secrets as volumes, not environment variables
+- Use short-lived tokens (OAuth, OIDC)
+- Rotate secrets regularly
+- Scan secrets with tools like gitleaks, trufflehog
+
+**DON'T:**
+- Commit secrets to Git
+- Print secrets in logs
+- Use long-lived credentials
+- Share secrets across environments
+
+## Performance Best Practices
+
+### Resource Management
+
+**Always set resource requests and limits:**
+```yaml
+steps:
+ - name: build
+ image: maven:3.8
+ resources:
+ requests:
+ cpu: 1000m
+ memory: 2Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+```
+
+**Guidelines:**
+- Set requests based on average usage
+- Set limits 1.5-2x higher than requests
+- Monitor actual usage: `kubectl top pods`
+- Use task-level resources for simplicity
+
+### Configure Pipeline Pruner
+
+**Automatic cleanup of old resources:**
+```yaml
+apiVersion: operator.tekton.dev/v1alpha1
+kind: TektonConfig
+metadata:
+ name: config
+spec:
+ pruner:
+ disabled: false
+ schedule: "0 8 * * *" # Daily at 8 AM
+ keep: 3 # Keep last 3 runs
+ resources:
+ - pipelinerun
+ - taskrun
+```
+
+**Manual cleanup:**
+```bash
+# Keep last 5 runs
+tkn pipelinerun delete --keep 5 -f
+
+# Delete runs older than 60 minutes
+tkn pipelinerun delete --keep-since 60 -f
+
+# Delete all failed runs
+tkn pipelinerun delete --all --failed -f
+```
+
+### Workspace Optimization
+
+**Use volumeClaimTemplate for isolation:**
+```yaml
+workspaces:
+ - name: workspace
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+```
+
+**Avoid PVC sharing conflicts:**
+- ReadWriteOnce: Limited to single node
+- ReadWriteMany: Best for Tekton but less common
+- Use emptyDir for temporary data
+- Use subPaths for organization
+
+### Caching Strategies
+
+**Maven cache:**
+```yaml
+workspaces:
+ - name: maven-cache
+ persistentVolumeClaim:
+ claimName: maven-cache-pvc
+
+steps:
+ - name: build
+ image: maven:3.8
+ env:
+ - name: MAVEN_OPTS
+ value: "-Dmaven.repo.local=$(workspaces.maven-cache.path)"
+```
+
+**Kaniko cache:**
+```yaml
+args:
+ - --cache=true
+ - --cache-repo=myregistry.com/cache
+ - --cache-ttl=24h
+```
+
+**npm cache:**
+```yaml
+workspaces:
+ - name: npm-cache
+
+steps:
+ - name: install
+ image: node:18
+ script: |
+ npm config set cache $(workspaces.npm-cache.path)
+ npm install
+```
+
+## Reliability Best Practices
+
+### Error Handling
+
+**Use retries for flaky operations:**
+```yaml
+tasks:
+ - name: flaky-network-test
+ retries: 3
+ taskRef:
+ name: integration-test
+```
+
+**Use onError for optional tasks:**
+```yaml
+tasks:
+ - name: optional-scan
+ onError: continue
+ taskRef:
+ name: security-scan
+```
+
+**Implement timeout:**
+```yaml
+spec:
+ timeouts:
+ pipeline: 2h
+ tasks: 1h
+ finally: 30m
+
+tasks:
+ - name: long-running
+ timeout: 45m
+```
+
+### Finally Tasks for Cleanup
+
+```yaml
+finally:
+ - name: cleanup-workspace
+ taskRef:
+ name: cleanup
+ workspaces:
+ - name: workspace
+ workspace: shared-data
+
+ - name: send-notification
+ taskRef:
+ name: notify
+ params:
+ - name: status
+ value: $(tasks.status)
+ - name: message
+ value: "Pipeline $(context.pipelineRun.name) $(tasks.status)"
+```
+
+### Idempotent Tasks
+
+```yaml
+# BAD: Not idempotent
+script: |
+ echo "data" >> file.txt # Appends on retry
+
+# GOOD: Idempotent
+script: |
+ echo "data" > file.txt # Overwrites on retry
+```
+
+## Maintainability Best Practices
+
+### Task Reusability
+
+**DO: Parameterize everything**
+```yaml
+params:
+ - name: image
+ - name: dockerfile
+ default: ./Dockerfile
+ - name: context
+ default: .
+```
+
+**DON'T: Hardcode values**
+```yaml
+# Anti-pattern
+args:
+ - --destination=myregistry.com/myimage:latest
+```
+
+### Use Tekton Hub
+
+**Check Hub before creating custom tasks:**
+```bash
+tkn hub search git
+tkn hub info task git-clone
+tkn hub install task git-clone
+```
+
+**Reference Hub tasks:**
+```yaml
+taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+```
+
+### Migration from Deprecated Features
+
+**AVOID: ClusterTasks (deprecated)**
+```yaml
+# Old
+taskRef:
+ name: git-clone
+ kind: ClusterTask
+```
+
+**USE: Resolvers**
+```yaml
+# New - Cluster resolver
+taskRef:
+ resolver: cluster
+ params:
+ - name: name
+ value: git-clone
+ - name: namespace
+ value: tekton-tasks
+
+# New - Hub resolver (preferred)
+taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+```
+
+**AVOID: PipelineResources (deprecated)**
+- Use Tasks with Results and Workspaces instead
+
+### Documentation
+
+**Document tasks comprehensively:**
+```yaml
+metadata:
+ name: build-app
+ labels:
+ app.kubernetes.io/version: "1.0"
+ annotations:
+ tekton.dev/pipelines.minVersion: "0.50.0"
+ tekton.dev/categories: Build Tools
+ tekton.dev/tags: build, maven
+spec:
+ description: |
+ Builds Java application using Maven.
+
+ This task compiles source code, runs tests,
+ and packages the application as a JAR file.
+
+ ## Parameters
+ - maven-goals: Maven goals to execute (default: clean package)
+ - settings-path: Path to custom settings.xml
+
+ ## Workspaces
+ - source: Source code directory
+ - maven-cache: Maven local repository cache (optional)
+
+ ## Results
+ - artifact-name: Name of the generated JAR file
+```
+
+### Versioning
+
+```yaml
+metadata:
+ labels:
+ app.kubernetes.io/version: "2.1.0"
+ version: "2.1.0"
+```
+
+## Anti-Patterns to Avoid
+
+### 1. Not Setting Resource Limits
+
+**Impact:** Poor scheduling, resource contention, cluster instability
+
+**Solution:**
+```yaml
+resources:
+ requests:
+ cpu: 500m
+ memory: 1Gi
+ limits:
+ cpu: 1000m
+ memory: 2Gi
+```
+
+### 2. Using :latest Image Tag
+
+**Impact:** Non-deterministic builds, cache issues
+
+**Solution:**
+```yaml
+image: maven:3.8.6-openjdk-17 # Specific version
+```
+
+### 3. Monolithic Tasks
+
+**Impact:** Poor reusability, difficult debugging
+
+**Solution:** Break into focused, single-responsibility tasks
+
+### 4. Ignoring Pipeline Pruner
+
+**Impact:** etcd bloat, performance degradation
+
+**Solution:** Configure automatic pruning (see above)
+
+### 5. Sharing ReadWriteOnce PVC in Parallel
+
+**Impact:** Pod scheduling failures
+
+**Solution:**
+- Use ReadWriteMany
+- Use volumeClaimTemplate
+- Avoid parallel tasks with shared workspace
+
+### 6. Results Over 4KB
+
+**Impact:** Task failures
+
+**Solution:** Use workspaces for large data
+
+### 7. Not Using Tekton Hub
+
+**Impact:** Reinventing the wheel, maintenance burden
+
+**Solution:** Check Hub first, contribute improvements
+
+### 8. Overly Permissive RBAC
+
+**Impact:** Security risks
+
+**Solution:** Least privilege principle
+
+### 9. Secrets in Logs
+
+**Impact:** Credential exposure
+
+**Solution:** Never print sensitive data
+
+### 10. Not Testing Tasks Isolation
+
+**Impact:** Pipeline failures
+
+**Solution:** Test TaskRuns independently before using in pipelines
+
+## Operating at Scale (Red Hat Lessons)
+
+### 1. Configure Pipeline Pruner
+Delete completed pods to free volumes and improve performance
+
+### 2. Set Resource Requests/Limits
+Scheduler performs poorly without them
+
+### 3. Understand Workload Bottlenecks
+Profile and optimize based on actual constraints
+
+### 4. Avoid PVC Sharing Conflicts
+Use volumeClaimTemplate or manage access modes carefully
+
+### 5. Monitor etcd Performance
+Prune old resources, use Tekton Results for long-term storage
+
+### 6. Plan for Multi-AZ Clusters
+PVCs are tied to specific availability zones
+
+### 7. Use Tekton Resolvers
+Replace ClusterTasks with cluster/hub/git resolvers
+
+### 8. Implement Retry Strategies
+Set retries for flaky network operations
+
+### 9. Version Control Everything
+Pin task/pipeline versions for stability
+
+### 10. Test at Scale
+Load test pipelines before production deployment
+
+## Monitoring and Observability
+
+### Tekton Dashboard
+
+```bash
+# Install Tekton Dashboard
+kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
+
+# Access dashboard
+kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097
+```
+
+### Prometheus Metrics
+
+**Tekton exports metrics:**
+- `tekton_pipelinerun_duration_seconds`
+- `tekton_pipelinerun_count`
+- `tekton_taskrun_duration_seconds`
+- `tekton_taskrun_count`
+
+### Logging Best Practices
+
+**Structured logging in tasks:**
+```yaml
+script: |
+ echo "[INFO] Starting build"
+ echo "[ERROR] Build failed: $ERROR_MSG"
+ echo "[SUCCESS] Build completed"
+```
+
+**Aggregate logs:**
+- Use Fluentd/Fluent Bit to collect logs
+- Send to Elasticsearch, Loki, or CloudWatch
+- Create dashboards in Grafana, Kibana
+
+### Alerting
+
+**Alert on:**
+- Pipeline failure rate exceeding threshold
+- Long-running pipelines
+- Resource quota exhaustion
+- PVC capacity
+- Failed webhook deliveries
+
+## Checklist
+
+### Security Checklist
+- [ ] Use workspace-based authentication
+- [ ] Create dedicated ServiceAccounts
+- [ ] Follow least privilege RBAC
+- [ ] Run containers as non-root
+- [ ] Scan images for vulnerabilities
+- [ ] Rotate credentials regularly
+- [ ] Don't commit secrets to Git
+- [ ] Use signed commits
+
+### Performance Checklist
+- [ ] Set resource requests/limits on all steps
+- [ ] Configure pipeline pruner
+- [ ] Use caching (Kaniko, Maven, npm)
+- [ ] Use volumeClaimTemplate for isolation
+- [ ] Monitor resource usage
+- [ ] Optimize Dockerfile layer caching
+- [ ] Use specific image tags
+
+### Reliability Checklist
+- [ ] Set retries for flaky operations
+- [ ] Use onError for optional tasks
+- [ ] Implement timeouts
+- [ ] Use finally tasks for cleanup
+- [ ] Write idempotent tasks
+- [ ] Test tasks in isolation
+- [ ] Monitor pipeline success rate
+
+### Maintainability Checklist
+- [ ] Check Tekton Hub before custom tasks
+- [ ] Parameterize all tasks
+- [ ] Document parameters and workspaces
+- [ ] Use resolvers (not ClusterTasks)
+- [ ] Version tasks and pipelines
+- [ ] Use consistent naming conventions
+- [ ] Organize tasks by function
dots/.config/claude/skills/Tekton/workflows/Build.md
@@ -0,0 +1,445 @@
+# Build Workflow
+
+Building container images with Tekton using Kaniko and Buildah.
+
+## When to Use
+
+- Building Docker/OCI container images
+- Pushing images to registries
+- Implementing caching strategies
+- Building without Docker daemon
+
+## Kaniko
+
+**Builds Docker images inside Kubernetes without Docker daemon**
+
+### Kaniko Task from Tekton Hub
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: TaskRun
+metadata:
+ name: kaniko-build
+spec:
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: kaniko
+ - name: version
+ value: "0.6.0"
+ params:
+ - name: IMAGE
+ value: myregistry.com/myapp:latest
+ - name: DOCKERFILE
+ value: ./Dockerfile
+ - name: CONTEXT
+ value: .
+ - name: EXTRA_ARGS
+ value:
+ - --cache=true
+ - --cache-ttl=24h
+ workspaces:
+ - name: source
+ persistentVolumeClaim:
+ claimName: source-pvc
+ - name: dockerconfig
+ secret:
+ secretName: docker-config
+```
+
+### Custom Kaniko Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: kaniko-build-push
+spec:
+ params:
+ - name: IMAGE
+ description: Image name with tag
+ - name: DOCKERFILE
+ description: Path to Dockerfile
+ default: ./Dockerfile
+ - name: CONTEXT
+ description: Build context
+ default: .
+ - name: BUILD_ARGS
+ type: array
+ description: Build arguments
+ default: []
+ workspaces:
+ - name: source
+ description: Source code
+ - name: dockerconfig
+ description: Docker credentials
+ results:
+ - name: IMAGE_DIGEST
+ description: Image digest
+ steps:
+ - name: build-and-push
+ image: gcr.io/kaniko-project/executor:latest
+ args:
+ - --dockerfile=$(params.DOCKERFILE)
+ - --context=$(workspaces.source.path)/$(params.CONTEXT)
+ - --destination=$(params.IMAGE)
+ - --digest-file=$(results.IMAGE_DIGEST.path)
+ - $(params.BUILD_ARGS[*])
+ env:
+ - name: DOCKER_CONFIG
+ value: $(workspaces.dockerconfig.path)
+ resources:
+ requests:
+ cpu: 1000m
+ memory: 1Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+```
+
+### Kaniko with Caching
+
+```yaml
+args:
+ - --dockerfile=./Dockerfile
+ - --context=.
+ - --destination=myregistry.com/myapp:latest
+ - --cache=true
+ - --cache-repo=myregistry.com/cache
+ - --cache-ttl=24h
+ - --compressed-caching=false
+```
+
+### Multi-Stage Dockerfile with Kaniko
+
+```dockerfile
+# Dockerfile
+FROM maven:3.8-openjdk-17 AS build
+WORKDIR /app
+COPY pom.xml .
+RUN mvn dependency:go-offline
+COPY src ./src
+RUN mvn package -DskipTests
+
+FROM eclipse-temurin:17-jre-alpine
+COPY --from=build /app/target/*.jar /app/app.jar
+ENTRYPOINT ["java", "-jar", "/app/app.jar"]
+```
+
+## Buildah
+
+**Builds OCI images with or without Dockerfiles**
+
+### Buildah Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: buildah-build
+spec:
+ params:
+ - name: IMAGE
+ description: Image name with tag
+ - name: DOCKERFILE
+ description: Path to Dockerfile
+ default: ./Dockerfile
+ - name: CONTEXT
+ description: Build context
+ default: .
+ - name: FORMAT
+ description: Image format (oci or docker)
+ default: oci
+ - name: TLS_VERIFY
+ description: Verify TLS certificates
+ default: "true"
+ workspaces:
+ - name: source
+ - name: dockerconfig
+ results:
+ - name: IMAGE_DIGEST
+ steps:
+ - name: build
+ image: quay.io/buildah/stable:latest
+ workingDir: $(workspaces.source.path)
+ script: |
+ #!/bin/bash
+ buildah --storage-driver=vfs bud \
+ --format=$(params.FORMAT) \
+ --tls-verify=$(params.TLS_VERIFY) \
+ --no-cache \
+ -f $(params.DOCKERFILE) \
+ -t $(params.IMAGE) \
+ $(params.CONTEXT)
+
+ buildah --storage-driver=vfs push \
+ --tls-verify=$(params.TLS_VERIFY) \
+ --digestfile=$(results.IMAGE_DIGEST.path) \
+ $(params.IMAGE) \
+ docker://$(params.IMAGE)
+ env:
+ - name: REGISTRY_AUTH_FILE
+ value: $(workspaces.dockerconfig.path)/config.json
+ securityContext:
+ privileged: true
+ resources:
+ requests:
+ cpu: 1000m
+ memory: 1Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+```
+
+### Buildah without Dockerfile
+
+```yaml
+steps:
+ - name: build-from-scratch
+ image: quay.io/buildah/stable
+ script: |
+ #!/bin/bash
+ # Create container from base image
+ container=$(buildah from alpine:latest)
+
+ # Install packages
+ buildah run $container -- apk add --no-cache python3
+
+ # Copy application
+ buildah copy $container app.py /app/
+
+ # Configure
+ buildah config --entrypoint '["python3", "/app/app.py"]' $container
+ buildah config --port 8080 $container
+
+ # Commit and push
+ buildah commit $container $(params.IMAGE)
+ buildah push $(params.IMAGE)
+```
+
+## Container Registry Authentication
+
+### Docker Config Secret
+
+```bash
+# Create docker config secret
+kubectl create secret docker-registry docker-config \
+ --docker-server=myregistry.com \
+ --docker-username=myuser \
+ --docker-password=mypassword \
+ --docker-email=myemail@example.com
+```
+
+**Or from existing config:**
+```bash
+kubectl create secret generic docker-config \
+ --from-file=config.json=$HOME/.docker/config.json
+```
+
+### Using in Workspace
+
+```yaml
+workspaces:
+ - name: dockerconfig
+ secret:
+ secretName: docker-config
+```
+
+### Harbor Integration
+
+```bash
+# Create secret for Harbor
+kubectl create secret docker-registry harbor-config \
+ --docker-server=harbor.example.com \
+ --docker-username=admin \
+ --docker-password=Harbor12345
+```
+
+### AWS ECR Authentication
+
+```yaml
+# Create ECR credentials task
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: ecr-login
+spec:
+ results:
+ - name: docker-config
+ steps:
+ - name: get-credentials
+ image: amazon/aws-cli
+ script: |
+ aws ecr get-login-password --region us-east-1 > $(results.docker-config.path)
+```
+
+## Complete Build Pipeline
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+ name: build-push-pipeline
+spec:
+ params:
+ - name: git-url
+ - name: git-revision
+ default: main
+ - name: image-name
+ - name: dockerfile
+ default: ./Dockerfile
+ workspaces:
+ - name: source-code
+ - name: docker-credentials
+ tasks:
+ # Clone repository
+ - name: clone
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+ workspaces:
+ - name: output
+ workspace: source-code
+ params:
+ - name: url
+ value: $(params.git-url)
+ - name: revision
+ value: $(params.git-revision)
+
+ # Extract version from git
+ - name: get-version
+ runAfter:
+ - clone
+ taskRef:
+ name: git-version
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ # Build and push with Kaniko
+ - name: build-push
+ runAfter:
+ - get-version
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: kaniko
+ workspaces:
+ - name: source
+ workspace: source-code
+ - name: dockerconfig
+ workspace: docker-credentials
+ params:
+ - name: IMAGE
+ value: $(params.image-name):$(tasks.get-version.results.version)
+ - name: DOCKERFILE
+ value: $(params.dockerfile)
+ - name: EXTRA_ARGS
+ value:
+ - --cache=true
+ - --compressed-caching=false
+
+ # Scan image for vulnerabilities
+ - name: scan
+ runAfter:
+ - build-push
+ taskRef:
+ name: trivy-scanner
+ params:
+ - name: IMAGE
+ value: $(params.image-name):$(tasks.get-version.results.version)
+ - name: DIGEST
+ value: $(tasks.build-push.results.IMAGE_DIGEST)
+```
+
+## Best Practices
+
+### Image Tagging
+- Use semantic versioning: `v1.2.3`
+- Include git commit SHA: `abc123`
+- Tag with branch name for development: `main`, `develop`
+- Always tag `latest` for main branch
+- Use immutable tags in production
+
+### Build Optimization
+- Use multi-stage Dockerfiles
+- Leverage build cache (Kaniko `--cache`)
+- Order Dockerfile commands from least to most frequently changed
+- Use `.dockerignore` to exclude unnecessary files
+- Minimize layer count
+
+### Security
+- Scan images for vulnerabilities (Trivy, Grype)
+- Use minimal base images (alpine, distroless)
+- Run as non-root user
+- Don't include secrets in images
+- Sign images (Cosign)
+
+### Resource Management
+- Set appropriate CPU/memory limits
+- Use caching to reduce build time
+- Clean up intermediate images
+- Limit concurrent builds
+
+## Troubleshooting
+
+### Kaniko Build Fails
+
+```bash
+# Check workspace is populated
+kubectl exec <pod-name> -c step-build-and-push -- ls /workspace/source
+
+# Check Dockerfile path
+kubectl exec <pod-name> -c step-build-and-push -- cat /workspace/source/Dockerfile
+
+# Check registry credentials
+kubectl get secret docker-config -o yaml
+
+# View detailed logs
+tkn taskrun logs <taskrun-name> -f
+```
+
+### Authentication Errors
+
+```bash
+# Verify secret format
+kubectl get secret docker-config -o jsonpath='{.data.config\.json}' | base64 -d | jq
+
+# Test registry access
+kubectl run test-registry --rm -i --tty --image=alpine -- sh
+apk add --no-cache docker
+docker login myregistry.com
+```
+
+### Image Push Fails
+
+```bash
+# Check network connectivity
+kubectl exec <pod-name> -- ping myregistry.com
+
+# Verify registry URL
+kubectl exec <pod-name> -- nslookup myregistry.com
+
+# Check TLS verification
+# Add --insecure flag for testing (not production!)
+```
+
+### Out of Memory
+
+```bash
+# Increase memory limits
+resources:
+ limits:
+ memory: 8Gi
+
+# Use Kaniko compressed caching
+- --compressed-caching=true
+
+# Reduce concurrent builds
+```
dots/.config/claude/skills/Tekton/workflows/GitOps.md
@@ -0,0 +1,612 @@
+# GitOps Workflow
+
+Integrating Tekton with GitOps tools (ArgoCD, Flux CD) for complete CI/CD automation.
+
+## When to Use
+
+- Implementing GitOps workflows
+- Integrating Tekton with ArgoCD or Flux
+- Automating deployments via Git
+- Separating CI and CD concerns
+- Managing multi-environment deployments
+
+## GitOps Architecture
+
+### Tekton + ArgoCD Pattern
+
+```
+┌──────────┐ ┌────────────┐ ┌──────────────┐ ┌─────────────┐
+│ GitHub │───▶│ Tekton │───▶│ GitOps Repo │───▶│ ArgoCD │
+│ (Code) │ │ (CI) │ │ (Manifests) │ │ (CD) │
+└──────────┘ └────────────┘ └──────────────┘ └─────────────┘
+ │ │
+ │ Build & Push │ Sync
+ ▼ ▼
+ ┌────────────┐ ┌─────────────┐
+ │ Registry │ │ Kubernetes │
+ └────────────┘ └─────────────┘
+```
+
+**Responsibilities:**
+- **Tekton (CI)**: Build, test, create container images
+- **ArgoCD (CD)**: Deploy manifests to Kubernetes
+
+**Benefits:**
+- Separation of concerns
+- Git as single source of truth
+- Declarative deployments
+- Automated rollback capabilities
+- Audit trail via Git history
+
+## Tekton CI Pipeline for GitOps
+
+### Complete CI Pipeline
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+ name: gitops-ci-pipeline
+spec:
+ params:
+ - name: git-url
+ description: Application source repository
+ - name: git-revision
+ description: Git commit/branch
+ default: main
+ - name: image-name
+ description: Container image name
+ - name: gitops-repo-url
+ description: GitOps repository URL
+ - name: gitops-branch
+ description: GitOps repository branch
+ default: main
+ - name: deployment-file
+ description: Path to deployment file
+ default: k8s/deployment.yaml
+
+ workspaces:
+ - name: source-code
+ - name: gitops-repo
+ - name: docker-credentials
+ - name: git-credentials
+
+ tasks:
+ # 1. Clone application source
+ - name: clone-source
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ workspaces:
+ - name: output
+ workspace: source-code
+ - name: ssh-directory
+ workspace: git-credentials
+ params:
+ - name: url
+ value: $(params.git-url)
+ - name: revision
+ value: $(params.git-revision)
+
+ # 2. Extract version from commit
+ - name: get-version
+ runAfter: [clone-source]
+ taskRef:
+ name: git-version
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ # 3. Run tests
+ - name: test
+ runAfter: [clone-source]
+ taskRef:
+ name: run-tests
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ # 4. Build and push image
+ - name: build-push
+ runAfter: [test, get-version]
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: kaniko
+ workspaces:
+ - name: source
+ workspace: source-code
+ - name: dockerconfig
+ workspace: docker-credentials
+ params:
+ - name: IMAGE
+ value: $(params.image-name):$(tasks.get-version.results.version)
+ - name: EXTRA_ARGS
+ value:
+ - --cache=true
+
+ # 5. Clone GitOps repository
+ - name: clone-gitops
+ runAfter: [build-push]
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ workspaces:
+ - name: output
+ workspace: gitops-repo
+ - name: ssh-directory
+ workspace: git-credentials
+ params:
+ - name: url
+ value: $(params.gitops-repo-url)
+ - name: revision
+ value: $(params.gitops-branch)
+
+ # 6. Update image tag in GitOps repo
+ - name: update-manifest
+ runAfter: [clone-gitops]
+ taskRef:
+ name: yq-update
+ workspaces:
+ - name: source
+ workspace: gitops-repo
+ params:
+ - name: file
+ value: $(params.deployment-file)
+ - name: expression
+ value: .spec.template.spec.containers[0].image = "$(params.image-name):$(tasks.get-version.results.version)"
+
+ # 7. Commit and push changes
+ - name: commit-push
+ runAfter: [update-manifest]
+ taskRef:
+ name: git-cli
+ workspaces:
+ - name: source
+ workspace: gitops-repo
+ - name: ssh-directory
+ workspace: git-credentials
+ params:
+ - name: GIT_USER_NAME
+ value: "Tekton Pipeline"
+ - name: GIT_USER_EMAIL
+ value: "tekton@example.com"
+ - name: GIT_SCRIPT
+ value: |
+ git add $(params.deployment-file)
+ git commit -m "Update image to $(params.image-name):$(tasks.get-version.results.version)"
+ git push origin $(params.gitops-branch)
+```
+
+### Update Manifest Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: yq-update
+spec:
+ params:
+ - name: file
+ description: YAML file to update
+ - name: expression
+ description: yq expression
+ workspaces:
+ - name: source
+ steps:
+ - name: update
+ image: mikefarah/yq:latest
+ workingDir: $(workspaces.source.path)
+ script: |
+ #!/bin/sh
+ yq eval -i '$(params.expression)' $(params.file)
+```
+
+### Git Commit Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: git-commit-push
+spec:
+ params:
+ - name: commit-message
+ - name: file-path
+ workspaces:
+ - name: source
+ - name: ssh-directory
+ steps:
+ - name: commit-push
+ image: alpine/git:latest
+ workingDir: $(workspaces.source.path)
+ env:
+ - name: GIT_SSH_COMMAND
+ value: ssh -i $(workspaces.ssh-directory.path)/id_rsa -o StrictHostKeyChecking=no
+ script: |
+ #!/bin/sh
+ set -e
+
+ git config user.name "Tekton Pipeline"
+ git config user.email "tekton@example.com"
+
+ git add $(params.file-path)
+ git commit -m "$(params.commit-message)"
+ git push origin HEAD
+```
+
+## ArgoCD Integration
+
+### ArgoCD Application
+
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: myapp
+ namespace: argocd
+spec:
+ project: default
+ source:
+ repoURL: https://github.com/org/gitops-repo
+ targetRevision: main
+ path: k8s
+ destination:
+ server: https://kubernetes.default.svc
+ namespace: production
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
+ syncOptions:
+ - CreateNamespace=true
+```
+
+### Trigger ArgoCD Sync from Tekton
+
+```yaml
+# Task to trigger ArgoCD sync
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: argocd-sync
+spec:
+ params:
+ - name: app-name
+ description: ArgoCD application name
+ - name: argocd-server
+ description: ArgoCD server URL
+ default: argocd-server.argocd.svc:443
+ steps:
+ - name: sync
+ image: argoproj/argocd:latest
+ script: |
+ #!/bin/sh
+ argocd app sync $(params.app-name) \
+ --server $(params.argocd-server) \
+ --auth-token $ARGOCD_TOKEN
+ env:
+ - name: ARGOCD_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: argocd-token
+ key: token
+```
+
+## Flux CD Integration
+
+### Flux ImageUpdateAutomation
+
+**Flux automatically updates images:**
+
+```yaml
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: myapp
+ namespace: flux-system
+spec:
+ image: myregistry.com/myapp
+ interval: 1m
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: myapp
+ namespace: flux-system
+spec:
+ imageRepositoryRef:
+ name: myapp
+ policy:
+ semver:
+ range: 1.x.x
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageUpdateAutomation
+metadata:
+ name: myapp
+ namespace: flux-system
+spec:
+ interval: 1m
+ sourceRef:
+ kind: GitRepository
+ name: gitops-repo
+ git:
+ checkout:
+ ref:
+ branch: main
+ commit:
+ author:
+ email: flux@example.com
+ name: Flux
+ messageTemplate: "Update image to {{range .Updated.Images}}{{println .}}{{end}}"
+ push:
+ branch: main
+ update:
+ path: ./k8s
+ strategy: Setters
+```
+
+### Tekton with Flux
+
+**Simpler Tekton pipeline:**
+```yaml
+# Tekton only builds and pushes
+# Flux automatically detects new image and updates manifests
+spec:
+ tasks:
+ - name: clone
+ - name: test
+ - name: build-push
+ # No manifest update needed - Flux handles it
+```
+
+## Multi-Environment GitOps
+
+### Directory Structure
+
+```
+gitops-repo/
+├── base/
+│ ├── deployment.yaml
+│ ├── service.yaml
+│ └── kustomization.yaml
+├── overlays/
+│ ├── dev/
+│ │ ├── kustomization.yaml
+│ │ └── patches/
+│ ├── staging/
+│ │ ├── kustomization.yaml
+│ │ └── patches/
+│ └── production/
+│ ├── kustomization.yaml
+│ └── patches/
+```
+
+### Kustomize Update Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: kustomize-set-image
+spec:
+ params:
+ - name: image
+ - name: overlay
+ default: dev
+ workspaces:
+ - name: source
+ steps:
+ - name: set-image
+ image: k8s.gcr.io/kustomize/kustomize:v5.0.0
+ workingDir: $(workspaces.source.path)/overlays/$(params.overlay)
+ script: |
+ kustomize edit set image app=$(params.image)
+```
+
+### Environment-Specific Pipelines
+
+```yaml
+# Dev pipeline - auto-deploy
+- name: update-dev
+ when:
+ - input: $(params.git-branch)
+ operator: in
+ values: [develop]
+ taskRef:
+ name: update-gitops
+ params:
+ - name: overlay
+ value: dev
+
+# Staging pipeline - auto-deploy
+- name: update-staging
+ when:
+ - input: $(params.git-branch)
+ operator: in
+ values: [main]
+ taskRef:
+ name: update-gitops
+ params:
+ - name: overlay
+ value: staging
+
+# Production - manual approval required
+- name: update-production
+ when:
+ - input: $(params.deploy-to-prod)
+ operator: in
+ values: ["true"]
+ taskRef:
+ name: update-gitops
+ params:
+ - name: overlay
+ value: production
+```
+
+## Git Credentials Management
+
+### SSH Key Secret
+
+```bash
+# Generate SSH key
+ssh-keygen -t ed25519 -C "tekton@example.com" -f tekton_key -N ""
+
+# Create secret
+kubectl create secret generic git-ssh-credentials \
+ --from-file=id_rsa=tekton_key \
+ --from-file=id_rsa.pub=tekton_key.pub \
+ --from-file=known_hosts=~/.ssh/known_hosts
+
+# Add public key to GitHub/GitLab as deploy key with write access
+```
+
+### Using SSH Credentials
+
+```yaml
+workspaces:
+ - name: ssh-directory
+ secret:
+ secretName: git-ssh-credentials
+ items:
+ - key: id_rsa
+ path: id_rsa
+ mode: 0600
+ - key: known_hosts
+ path: known_hosts
+```
+
+## Best Practices
+
+### Repository Structure
+- Separate application and GitOps repositories
+- Use Kustomize or Helm for multi-environment management
+- Version GitOps manifests
+- Protect main branch with pull requests
+
+### CI Pipeline
+- Build and test in Tekton
+- Push images with semantic versioning
+- Update GitOps repo via automation
+- Sign commits for traceability
+
+### CD with ArgoCD/Flux
+- Enable auto-sync for development
+- Require manual approval for production
+- Configure sync windows for production
+- Set up health checks and rollback
+
+### Security
+- Use SSH keys with write-only access to GitOps repo
+- Rotate credentials regularly
+- Scan container images before pushing
+- Use signed commits
+
+### Monitoring
+- Monitor ArgoCD sync status
+- Alert on sync failures
+- Track deployment frequency
+- Measure lead time for changes
+
+## Complete GitOps Example
+
+```yaml
+# PipelineRun with all parameters
+apiVersion: tekton.dev/v1
+kind: PipelineRun
+metadata:
+ generateName: gitops-ci-run-
+spec:
+ pipelineRef:
+ name: gitops-ci-pipeline
+ params:
+ - name: git-url
+ value: https://github.com/org/myapp
+ - name: git-revision
+ value: main
+ - name: image-name
+ value: myregistry.com/myapp
+ - name: gitops-repo-url
+ value: git@github.com:org/gitops-repo.git
+ - name: gitops-branch
+ value: main
+ - name: deployment-file
+ value: overlays/production/kustomization.yaml
+ workspaces:
+ - name: source-code
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ - name: gitops-repo
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 500Mi
+ - name: docker-credentials
+ secret:
+ secretName: docker-config
+ - name: git-credentials
+ secret:
+ secretName: git-ssh-credentials
+ serviceAccountName: gitops-pipeline-sa
+```
+
+## Troubleshooting
+
+### Manifest Update Fails
+
+```bash
+# Check workspace contents
+kubectl exec <pod-name> -- ls /workspace/gitops-repo
+
+# Verify yq/kustomize syntax
+kubectl logs <pod-name> -c step-update
+```
+
+### Git Push Fails
+
+```bash
+# Check SSH credentials
+kubectl get secret git-ssh-credentials -o yaml
+
+# Test SSH connection
+kubectl run test-git --rm -i --tty --image=alpine/git -- sh
+apk add openssh-client
+ssh -T git@github.com
+```
+
+### ArgoCD Not Syncing
+
+```bash
+# Check ArgoCD application
+kubectl get application myapp -n argocd
+
+# View sync status
+argocd app get myapp
+
+# Manual sync
+argocd app sync myapp
+```
+
+### Wrong Image Tag
+
+```bash
+# Check task results
+kubectl get pipelinerun <name> -o jsonpath='{.status.taskRuns}'
+
+# Verify manifest update
+kubectl logs <pod-name> -c step-update
+```
dots/.config/claude/skills/Tekton/workflows/Pipelines.md
@@ -0,0 +1,621 @@
+# Pipelines Workflow
+
+Creating and managing Tekton Pipelines to orchestrate multiple Tasks into complete CI/CD workflows.
+
+## When to Use
+
+- Orchestrating multiple tasks
+- Defining task dependencies and execution order
+- Creating complete CI/CD workflows
+- Managing data flow between tasks
+- Building complex pipelines
+
+## Pipeline Structure
+
+### Basic Pipeline
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+ name: build-and-deploy
+spec:
+ params:
+ - name: git-url
+ type: string
+ - name: image-name
+ type: string
+ workspaces:
+ - name: shared-data
+ tasks:
+ - name: fetch-source
+ taskRef:
+ name: git-clone
+ workspaces:
+ - name: output
+ workspace: shared-data
+ params:
+ - name: url
+ value: $(params.git-url)
+
+ - name: build-image
+ taskRef:
+ name: kaniko
+ runAfter:
+ - fetch-source
+ workspaces:
+ - name: source
+ workspace: shared-data
+ params:
+ - name: IMAGE
+ value: $(params.image-name)
+```
+
+## Task Execution Control
+
+### Sequential Execution
+
+```yaml
+tasks:
+ - name: test
+ taskRef:
+ name: run-tests
+
+ - name: build
+ taskRef:
+ name: build-image
+ runAfter:
+ - test # Waits for test to complete
+```
+
+### Parallel Execution
+
+```yaml
+tasks:
+ - name: lint
+ taskRef:
+ name: lint-code
+ # No runAfter - starts immediately
+
+ - name: test
+ taskRef:
+ name: run-tests
+ # No runAfter - starts in parallel with lint
+
+ - name: security-scan
+ taskRef:
+ name: trivy-scan
+ # No runAfter - starts in parallel
+
+ - name: build
+ taskRef:
+ name: build-image
+ runAfter:
+ - lint
+ - test
+ - security-scan # Waits for all three
+```
+
+### Conditional Execution
+
+```yaml
+tasks:
+ - name: deploy-staging
+ when:
+ - input: "$(params.environment)"
+ operator: in
+ values: ["staging", "production"]
+ taskRef:
+ name: deploy
+
+ - name: deploy-prod
+ when:
+ - input: "$(params.environment)"
+ operator: in
+ values: ["production"]
+ - input: "$(tasks.test.results.status)"
+ operator: in
+ values: ["passed"]
+ runAfter:
+ - deploy-staging
+ taskRef:
+ name: deploy-production
+```
+
+**When Expression Operators:**
+- `in`: Value is in list
+- `notin`: Value is not in list
+
+## Passing Data Between Tasks
+
+### Using Results
+
+```yaml
+tasks:
+ - name: get-version
+ taskRef:
+ name: calculate-version
+ # Task emits result: version
+
+ - name: build-image
+ taskRef:
+ name: kaniko
+ runAfter:
+ - get-version
+ params:
+ - name: IMAGE
+ value: $(params.image-name):$(tasks.get-version.results.version)
+```
+
+### Using Workspaces
+
+```yaml
+workspaces:
+ - name: source-code
+
+tasks:
+ - name: clone
+ taskRef:
+ name: git-clone
+ workspaces:
+ - name: output
+ workspace: source-code
+
+ - name: test
+ taskRef:
+ name: run-tests
+ runAfter:
+ - clone
+ workspaces:
+ - name: source
+ workspace: source-code # Shares data with clone task
+```
+
+## Finally Tasks
+
+**Finally tasks run after all pipeline tasks complete, regardless of success or failure.**
+
+```yaml
+finally:
+ - name: cleanup-workspace
+ taskRef:
+ name: cleanup
+ workspaces:
+ - name: workspace
+ workspace: shared-data
+
+ - name: send-notification
+ taskRef:
+ name: send-slack-message
+ params:
+ - name: status
+ value: $(tasks.status) # SUCCESS or FAILURE
+ - name: message
+ value: "Pipeline $(context.pipelineRun.name) completed"
+```
+
+## Complete Pipeline Example
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+ name: nodejs-ci-cd
+spec:
+ params:
+ - name: git-url
+ description: Git repository URL
+ - name: git-revision
+ description: Git revision
+ default: main
+ - name: image-name
+ description: Container image name
+ - name: deploy-namespace
+ description: Kubernetes namespace
+ default: default
+
+ workspaces:
+ - name: source-code
+ - name: docker-credentials
+
+ tasks:
+ # Fetch source code
+ - name: clone
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+ workspaces:
+ - name: output
+ workspace: source-code
+ params:
+ - name: url
+ value: $(params.git-url)
+ - name: revision
+ value: $(params.git-revision)
+
+ # Parallel: Lint and test
+ - name: lint
+ taskRef:
+ name: npm-lint
+ runAfter:
+ - clone
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ - name: test
+ taskRef:
+ name: npm-test
+ runAfter:
+ - clone
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ # Security scan
+ - name: security-scan
+ taskRef:
+ name: trivy-scan
+ runAfter:
+ - clone
+ workspaces:
+ - name: source
+ workspace: source-code
+
+ # Build and push image
+ - name: build-push
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: kaniko
+ - name: version
+ value: "0.6.0"
+ runAfter:
+ - lint
+ - test
+ - security-scan
+ workspaces:
+ - name: source
+ workspace: source-code
+ - name: dockerconfig
+ workspace: docker-credentials
+ params:
+ - name: IMAGE
+ value: $(params.image-name):$(tasks.clone.results.commit)
+
+ # Deploy to Kubernetes
+ - name: deploy
+ taskRef:
+ name: kubernetes-deploy
+ runAfter:
+ - build-push
+ params:
+ - name: image
+ value: $(params.image-name):$(tasks.clone.results.commit)
+ - name: namespace
+ value: $(params.deploy-namespace)
+
+ finally:
+ - name: cleanup
+ taskRef:
+ name: cleanup-workspace
+ workspaces:
+ - name: workspace
+ workspace: source-code
+
+ - name: notify
+ taskRef:
+ name: send-notification
+ params:
+ - name: pipeline-status
+ value: $(tasks.status)
+```
+
+## PipelineRun
+
+### Creating PipelineRun
+
+**Using tkn CLI:**
+```bash
+tkn pipeline start nodejs-ci-cd \
+ -p git-url=https://github.com/myorg/myapp \
+ -p git-revision=main \
+ -p image-name=myregistry.com/myapp \
+ -p deploy-namespace=production \
+ -w name=source-code,volumeClaimTemplateFile=pvc-template.yaml \
+ -w name=docker-credentials,secret=docker-config \
+ --serviceaccount=pipeline-sa \
+ --showlog
+```
+
+**Declarative YAML:**
+```yaml
+apiVersion: tekton.dev/v1
+kind: PipelineRun
+metadata:
+ generateName: nodejs-ci-cd-run-
+spec:
+ pipelineRef:
+ name: nodejs-ci-cd
+ params:
+ - name: git-url
+ value: https://github.com/myorg/myapp
+ - name: git-revision
+ value: main
+ - name: image-name
+ value: myregistry.com/myapp
+ - name: deploy-namespace
+ value: production
+ workspaces:
+ - name: source-code
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ - name: docker-credentials
+ secret:
+ secretName: docker-config
+ serviceAccountName: pipeline-sa
+ timeout: 1h
+```
+
+## Advanced Patterns
+
+### Matrix Execution (Beta)
+
+**Run task with multiple parameter combinations:**
+```yaml
+tasks:
+ - name: test-platforms
+ taskRef:
+ name: run-tests
+ matrix:
+ params:
+ - name: platform
+ value:
+ - linux/amd64
+ - linux/arm64
+ - name: version
+ value:
+ - "18"
+ - "20"
+ # Creates 4 TaskRuns: all combinations of platform x version
+```
+
+### Custom Task References
+
+```yaml
+tasks:
+ - name: custom-action
+ taskRef:
+ apiVersion: custom.dev/v1
+ kind: CustomTask
+ name: my-custom-task
+```
+
+### Retries
+
+```yaml
+tasks:
+ - name: flaky-test
+ retries: 3
+ taskRef:
+ name: integration-tests
+```
+
+### Timeouts
+
+```yaml
+# Pipeline-level timeout
+spec:
+ timeouts:
+ pipeline: 2h
+ tasks: 1h
+ finally: 30m
+
+# Task-level timeout
+tasks:
+ - name: long-running
+ timeout: 45m
+ taskRef:
+ name: build-task
+```
+
+### OnError Behavior
+
+```yaml
+tasks:
+ - name: optional-scan
+ onError: continue # Continue even if this task fails
+ taskRef:
+ name: security-scan
+```
+
+## Common Pipeline Patterns
+
+### Build-Test-Deploy
+
+```yaml
+spec:
+ tasks:
+ - name: fetch-repo
+ - name: run-tests
+ runAfter: [fetch-repo]
+ - name: build-image
+ runAfter: [run-tests]
+ - name: deploy
+ runAfter: [build-image]
+```
+
+### Fan-Out, Fan-In
+
+```yaml
+spec:
+ tasks:
+ - name: clone
+
+ # Fan out (parallel)
+ - name: unit-test
+ runAfter: [clone]
+ - name: integration-test
+ runAfter: [clone]
+ - name: e2e-test
+ runAfter: [clone]
+
+ # Fan in (wait for all)
+ - name: build
+ runAfter: [unit-test, integration-test, e2e-test]
+```
+
+### Multi-Environment Deploy
+
+```yaml
+spec:
+ params:
+ - name: environment
+ tasks:
+ - name: build
+
+ - name: deploy-dev
+ when:
+ - input: $(params.environment)
+ operator: in
+ values: [dev, staging, production]
+ runAfter: [build]
+
+ - name: deploy-staging
+ when:
+ - input: $(params.environment)
+ operator: in
+ values: [staging, production]
+ runAfter: [deploy-dev]
+
+ - name: deploy-production
+ when:
+ - input: $(params.environment)
+ operator: in
+ values: [production]
+ runAfter: [deploy-staging]
+```
+
+## Monitoring and Debugging
+
+### View Pipeline Status
+
+```bash
+# List pipelineruns
+tkn pipelinerun list
+
+# Describe pipelinerun
+tkn pipelinerun describe my-run
+
+# View logs
+tkn pipelinerun logs my-run -f
+
+# Check task status
+kubectl get pipelinerun my-run -o jsonpath='{.status.taskRuns}'
+```
+
+### Pipeline Metrics
+
+```bash
+# Get pipeline duration
+kubectl get pipelinerun my-run -o jsonpath='{.status.startTime}'
+kubectl get pipelinerun my-run -o jsonpath='{.status.completionTime}'
+
+# Get task durations
+kubectl get pipelinerun my-run -o json | \
+ jq '.status.taskRuns[] | {name: .pipelineTaskName, duration: (.status.completionTime - .status.startTime)}'
+```
+
+## Best Practices
+
+### Pipeline Design
+- Keep pipelines focused on single workflow (CI or CD, not both)
+- Use descriptive task names
+- Group related tasks with proper dependencies
+- Use finally tasks for cleanup and notifications
+- Set appropriate timeouts
+
+### Data Flow
+- Use Results for small data (<4KB): commits, versions, flags
+- Use Workspaces for larger data: source code, build artifacts
+- Use PVC with volumeClaimTemplate for isolation
+- Be aware of PVC access mode limitations for parallel tasks
+
+### Error Handling
+- Set retries for flaky network operations
+- Use onError: continue for optional tasks
+- Use finally tasks for cleanup
+- Implement proper logging in tasks
+
+### Performance
+- Run independent tasks in parallel
+- Use caching workspaces (Maven, npm, Go modules)
+- Set resource limits to prevent resource contention
+- Use pipeline pruner to clean old runs
+
+### Security
+- Use dedicated ServiceAccounts
+- Follow least privilege for RBAC
+- Use Secrets for credentials
+- Never hardcode sensitive data in pipelines
+
+## Troubleshooting
+
+### Pipeline Won't Start
+
+```bash
+# Check pipeline exists
+kubectl get pipeline my-pipeline
+
+# Check pipelinerun
+kubectl describe pipelinerun my-run
+
+# Check service account
+kubectl get serviceaccount pipeline-sa
+
+# Check RBAC
+kubectl auth can-i create pipelineruns
+```
+
+### Task Dependencies Not Working
+
+```bash
+# Check runAfter is correct
+kubectl get pipeline my-pipeline -o yaml | grep -A 5 runAfter
+
+# Check when expressions
+kubectl get pipelinerun my-run -o jsonpath='{.status.skippedTasks}'
+```
+
+### Workspace Issues
+
+```bash
+# Check workspace bindings
+kubectl get pipelinerun my-run -o jsonpath='{.spec.workspaces}'
+
+# Check PVC exists
+kubectl get pvc
+
+# Check PVC is bound
+kubectl get pvc my-pvc -o jsonpath='{.status.phase}'
+```
+
+### Finally Tasks Not Running
+
+```bash
+# Check pipeline status
+kubectl get pipelinerun my-run -o jsonpath='{.status.conditions}'
+
+# View finally task status
+kubectl get pipelinerun my-run -o jsonpath='{.status.finallyStatus}'
+```
dots/.config/claude/skills/Tekton/workflows/Tasks.md
@@ -0,0 +1,778 @@
+# Tasks Workflow
+
+Creating and managing Tekton Tasks - the fundamental building blocks of Tekton Pipelines.
+
+## When to Use
+
+- Creating new Tasks
+- Defining Steps and workspaces
+- Parameterizing tasks for reusability
+- Emitting Results
+- Understanding TaskRuns
+
+## Task Anatomy
+
+### Basic Task Structure
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: my-task
+ namespace: default
+spec:
+ description: |
+ A brief description of what this task does
+ params:
+ - name: param-name
+ type: string
+ description: Description of the parameter
+ default: "default-value"
+ workspaces:
+ - name: workspace-name
+ description: Workspace for source code
+ mountPath: /workspace/source
+ results:
+ - name: result-name
+ description: Description of the result
+ steps:
+ - name: step-name
+ image: alpine:latest
+ script: |
+ #!/bin/sh
+ echo "Hello from step"
+```
+
+### Complete Task Example
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: build-app
+ labels:
+ app.kubernetes.io/version: "1.0"
+spec:
+ description: Build application using Maven
+ params:
+ - name: maven-image
+ type: string
+ description: Maven image to use
+ default: maven:3.8-openjdk-17
+ - name: goals
+ type: array
+ description: Maven goals to execute
+ default:
+ - clean
+ - package
+ - name: settings-path
+ type: string
+ description: Path to Maven settings.xml
+ default: ""
+ workspaces:
+ - name: source
+ description: Source code workspace
+ - name: maven-cache
+ description: Maven local repository cache
+ optional: true
+ results:
+ - name: artifact-name
+ description: Name of the built artifact
+ - name: build-timestamp
+ description: When the build completed
+ steps:
+ - name: build
+ image: $(params.maven-image)
+ workingDir: $(workspaces.source.path)
+ script: |
+ #!/bin/bash
+ set -e
+
+ # Use cache if available
+ if [ "$(workspaces.maven-cache.bound)" == "true" ]; then
+ export MAVEN_OPTS="-Dmaven.repo.local=$(workspaces.maven-cache.path)"
+ fi
+
+ # Add settings if provided
+ SETTINGS_ARG=""
+ if [ -n "$(params.settings-path)" ]; then
+ SETTINGS_ARG="-s $(params.settings-path)"
+ fi
+
+ # Run Maven build
+ mvn $SETTINGS_ARG $(params.goals[*])
+
+ # Output results
+ ARTIFACT=$(ls target/*.jar | head -n 1 | xargs basename)
+ echo -n "$ARTIFACT" > $(results.artifact-name.path)
+ echo -n "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > $(results.build-timestamp.path)
+ resources:
+ requests:
+ cpu: 500m
+ memory: 1Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+```
+
+## Parameters
+
+### Parameter Types
+
+**String parameter:**
+```yaml
+params:
+ - name: git-url
+ type: string
+ description: Git repository URL
+ default: ""
+```
+
+**Array parameter:**
+```yaml
+params:
+ - name: build-args
+ type: array
+ description: Build arguments
+ default: []
+```
+
+**Object parameter (Beta):**
+```yaml
+params:
+ - name: gitconfig
+ type: object
+ description: Git configuration
+ properties:
+ username:
+ type: string
+ email:
+ type: string
+ default:
+ username: ""
+ email: ""
+```
+
+### Using Parameters in Steps
+
+```yaml
+steps:
+ - name: use-params
+ image: alpine
+ script: |
+ echo "String param: $(params.git-url)"
+ echo "Array param: $(params.build-args[*])"
+ echo "Array first element: $(params.build-args[0])"
+ echo "Object param: $(params.gitconfig.username)"
+```
+
+### Parameter Validation
+
+```yaml
+params:
+ - name: environment
+ type: string
+ description: Deployment environment
+ default: "dev"
+ # Validation happens at runtime via when expressions or script logic
+```
+
+## Workspaces
+
+### Declaring Workspaces
+
+```yaml
+workspaces:
+ - name: source
+ description: Source code directory
+ mountPath: /workspace/source # Optional custom mount path
+ - name: cache
+ description: Build cache
+ optional: true # Task can run without this workspace
+ - name: config
+ description: Configuration files
+ readOnly: true # Workspace is read-only
+```
+
+### Workspace Variables
+
+```yaml
+script: |
+ # Path to workspace
+ echo "Workspace path: $(workspaces.source.path)"
+
+ # PVC name (if using PVC)
+ echo "PVC name: $(workspaces.source.claim)"
+
+ # Check if workspace is bound
+ if [ "$(workspaces.source.bound)" == "true" ]; then
+ echo "Workspace is available"
+ fi
+```
+
+### Workspace Use Cases
+
+**PVC workspace (shared data):**
+```yaml
+# In TaskRun
+workspaces:
+ - name: source
+ persistentVolumeClaim:
+ claimName: shared-workspace
+```
+
+**emptyDir workspace (temporary):**
+```yaml
+# In TaskRun
+workspaces:
+ - name: temp
+ emptyDir: {}
+```
+
+**ConfigMap workspace (configuration):**
+```yaml
+# In TaskRun
+workspaces:
+ - name: config
+ configMap:
+ name: app-config
+```
+
+**Secret workspace (credentials):**
+```yaml
+# In TaskRun
+workspaces:
+ - name: credentials
+ secret:
+ secretName: git-credentials
+```
+
+## Steps
+
+### Step Structure
+
+```yaml
+steps:
+ - name: step-name
+ image: container-image
+ command:
+ - /bin/sh
+ args:
+ - -c
+ - echo "Hello"
+ env:
+ - name: ENV_VAR
+ value: "value"
+ workingDir: /workspace
+ script: |
+ #!/bin/sh
+ echo "Multi-line script"
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+```
+
+### Multiple Steps (Sequential)
+
+```yaml
+steps:
+ - name: fetch-dependencies
+ image: node:18
+ script: |
+ npm install
+
+ - name: run-tests
+ image: node:18
+ script: |
+ npm test
+
+ - name: build
+ image: node:18
+ script: |
+ npm run build
+```
+
+### Step Script vs Command
+
+**Using script (recommended):**
+```yaml
+steps:
+ - name: build
+ image: maven:3.8
+ script: |
+ #!/bin/bash
+ set -e
+ mvn clean package
+```
+
+**Using command/args:**
+```yaml
+steps:
+ - name: build
+ image: maven:3.8
+ command:
+ - mvn
+ args:
+ - clean
+ - package
+```
+
+### Environment Variables
+
+```yaml
+steps:
+ - name: build
+ image: alpine
+ env:
+ # From parameter
+ - name: GIT_URL
+ value: $(params.git-url)
+
+ # From secret
+ - name: API_KEY
+ valueFrom:
+ secretKeyRef:
+ name: api-credentials
+ key: api_key
+
+ # From configMap
+ - name: CONFIG_PATH
+ valueFrom:
+ configMapKeyRef:
+ name: app-config
+ key: config_path
+
+ # Built-in Tekton variables
+ - name: TASK_NAME
+ value: $(context.task.name)
+ - name: TASKRUN_NAME
+ value: $(context.taskRun.name)
+ - name: TASKRUN_NAMESPACE
+ value: $(context.taskRun.namespace)
+```
+
+## Results
+
+### Emitting Results
+
+**IMPORTANT:** Results are limited to 4KB. Use workspaces for larger data.
+
+```yaml
+results:
+ - name: commit-sha
+ description: Git commit SHA
+ - name: image-digest
+ description: Container image digest
+ - name: test-status
+ description: Test pass/fail status
+
+steps:
+ - name: get-commit
+ image: alpine/git
+ script: |
+ git rev-parse HEAD > $(results.commit-sha.path)
+
+ - name: build-image
+ image: gcr.io/kaniko-project/executor
+ script: |
+ # Kaniko outputs digest to /kaniko/digest
+ cp /kaniko/digest $(results.image-digest.path)
+
+ - name: run-tests
+ image: node:18
+ script: |
+ if npm test; then
+ echo -n "passed" > $(results.test-status.path)
+ else
+ echo -n "failed" > $(results.test-status.path)
+ fi
+```
+
+### Result Size Considerations
+
+**Good (small data):**
+- Commit SHAs
+- Image digests
+- Version numbers
+- Status flags
+- Ephemeral namespace names
+
+**Bad (use workspaces instead):**
+- Full build logs
+- Large JSON payloads
+- File contents
+- Binary data
+
+## Resource Management
+
+### Step Resources
+
+```yaml
+steps:
+ - name: build
+ image: maven:3.8
+ resources:
+ requests:
+ cpu: 500m
+ memory: 1Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+```
+
+### Task-Level Resources (Alpha)
+
+```yaml
+# In TaskRun, not Task definition
+apiVersion: tekton.dev/v1beta1
+kind: TaskRun
+spec:
+ taskRef:
+ name: build-task
+ computeResources:
+ requests:
+ cpu: "1"
+ memory: "2Gi"
+ limits:
+ cpu: "2"
+ memory: "4Gi"
+```
+
+**Best Practices:**
+- Always set resource requests for scheduler
+- Set limits 1.5-2x higher than requests
+- Monitor actual usage with `kubectl top pods`
+- Use task-level resources for simplicity when all steps have similar requirements
+
+## Security Context
+
+### Task Security
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: secure-task
+spec:
+ steps:
+ - name: build
+ image: alpine
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ runAsGroup: 1000
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ capabilities:
+ drop:
+ - ALL
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ volumes:
+ - name: tmp
+ emptyDir: {}
+```
+
+## TaskRun
+
+### Creating TaskRun
+
+**Imperative (tkn):**
+```bash
+tkn task start my-task \
+ -p param1=value1 \
+ -p param2=value2 \
+ -w name=source,claimName=my-pvc \
+ --showlog
+```
+
+**Declarative (YAML):**
+```yaml
+apiVersion: tekton.dev/v1
+kind: TaskRun
+metadata:
+ name: my-taskrun
+spec:
+ taskRef:
+ name: my-task
+ params:
+ - name: param1
+ value: "value1"
+ - name: param2
+ value: "value2"
+ workspaces:
+ - name: source
+ persistentVolumeClaim:
+ claimName: my-pvc
+ serviceAccountName: pipeline-sa
+ timeout: 1h
+```
+
+### TaskRun with Resolvers
+
+**Hub resolver:**
+```yaml
+apiVersion: tekton.dev/v1
+kind: TaskRun
+metadata:
+ name: git-clone-run
+spec:
+ taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+ params:
+ - name: url
+ value: https://github.com/myorg/myrepo
+ workspaces:
+ - name: output
+ emptyDir: {}
+```
+
+**Cluster resolver:**
+```yaml
+apiVersion: tekton.dev/v1
+kind: TaskRun
+metadata:
+ name: shared-task-run
+spec:
+ taskRef:
+ resolver: cluster
+ params:
+ - name: name
+ value: shared-task
+ - name: namespace
+ value: tekton-tasks
+```
+
+### TaskRun Status
+
+```bash
+# View taskrun status
+kubectl get taskrun my-taskrun
+
+# Describe for details
+kubectl describe taskrun my-taskrun
+
+# Get status conditions
+kubectl get taskrun my-taskrun -o jsonpath='{.status.conditions}'
+
+# Get results
+kubectl get taskrun my-taskrun -o jsonpath='{.status.taskResults}'
+```
+
+## Reusable Task Patterns
+
+### Git Clone Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: git-clone-custom
+spec:
+ params:
+ - name: url
+ description: Git repository URL
+ - name: revision
+ description: Branch, tag, or commit
+ default: "main"
+ - name: depth
+ description: Shallow clone depth
+ default: "1"
+ workspaces:
+ - name: output
+ description: Clone destination
+ steps:
+ - name: clone
+ image: alpine/git:latest
+ script: |
+ git clone --depth=$(params.depth) \
+ --branch=$(params.revision) \
+ $(params.url) \
+ $(workspaces.output.path)
+```
+
+### Test Runner Task
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: run-tests
+spec:
+ params:
+ - name: test-command
+ description: Command to run tests
+ default: "npm test"
+ workspaces:
+ - name: source
+ description: Source code
+ results:
+ - name: test-result
+ description: Test pass/fail
+ steps:
+ - name: test
+ image: node:18
+ workingDir: $(workspaces.source.path)
+ script: |
+ if $(params.test-command); then
+ echo -n "passed" > $(results.test-result.path)
+ else
+ echo -n "failed" > $(results.test-result.path)
+ exit 1
+ fi
+```
+
+## Best Practices
+
+### Task Design
+- Keep tasks focused on single responsibility
+- Use parameters for configurability (no hardcoded values)
+- Document all parameters, workspaces, and results
+- Emit results for small data (<4KB)
+- Use workspaces for sharing larger data
+- Set resource requests/limits for all steps
+- Use non-root containers when possible
+
+### Reusability
+- Check Tekton Hub before creating custom tasks
+- Make tasks generic and parameterized
+- Use descriptive names and labels
+- Version your tasks (labels/annotations)
+- Write comprehensive descriptions
+
+### Security
+- Run as non-root user
+- Use read-only root filesystem when possible
+- Drop unnecessary capabilities
+- Use workspace-based authentication
+- Avoid embedding secrets in task definitions
+
+### Performance
+- Use caching workspaces (Maven, npm, Go)
+- Set appropriate resource limits
+- Use specific image tags (not :latest)
+- Minimize image sizes (alpine, distroless)
+- Use build caches (Kaniko, Buildah)
+
+## Common Patterns
+
+### Conditional Execution
+
+```yaml
+steps:
+ - name: deploy-to-prod
+ image: kubectl
+ script: |
+ if [ "$(params.environment)" = "production" ]; then
+ kubectl apply -f production.yaml
+ else
+ echo "Skipping production deployment"
+ fi
+```
+
+### Error Handling
+
+```yaml
+steps:
+ - name: build-with-retry
+ image: maven:3.8
+ script: |
+ #!/bin/bash
+ set -e
+
+ MAX_RETRIES=3
+ RETRY_COUNT=0
+
+ until mvn clean package; do
+ RETRY_COUNT=$((RETRY_COUNT+1))
+ if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
+ echo "Build failed after $MAX_RETRIES attempts"
+ exit 1
+ fi
+ echo "Build failed, retrying ($RETRY_COUNT/$MAX_RETRIES)..."
+ sleep 5
+ done
+```
+
+### Using Previous Step Results
+
+```yaml
+steps:
+ - name: get-version
+ image: alpine
+ script: |
+ echo -n "1.2.3" > /tmp/version
+
+ - name: use-version
+ image: alpine
+ script: |
+ VERSION=$(cat /tmp/version)
+ echo "Building version: $VERSION"
+```
+
+## Troubleshooting
+
+### Task Won't Start
+
+```bash
+# Check task exists
+kubectl get task my-task
+
+# Check taskrun status
+kubectl describe taskrun my-taskrun
+
+# Check events
+kubectl get events --sort-by=.metadata.creationTimestamp
+```
+
+### Step Failing
+
+```bash
+# View logs
+tkn taskrun logs my-taskrun -f
+
+# Check specific step
+kubectl logs <pod-name> -c step-<step-name>
+
+# Check previous container logs if crashed
+kubectl logs <pod-name> -c step-<step-name> --previous
+```
+
+### Workspace Issues
+
+```bash
+# Check PVC exists and is bound
+kubectl get pvc
+
+# Check workspace binding in taskrun
+kubectl get taskrun my-taskrun -o jsonpath='{.spec.workspaces}'
+
+# Check pod volumes
+kubectl get pod <pod-name> -o jsonpath='{.spec.volumes}'
+```
+
+### Results Not Available
+
+```bash
+# Check result was written
+kubectl get taskrun my-taskrun -o jsonpath='{.status.taskResults}'
+
+# Check step completed successfully
+kubectl get taskrun my-taskrun -o jsonpath='{.status.steps}'
+
+# Verify result size (<4KB)
+kubectl logs <pod-name> -c step-<step-name> | wc -c
+```
dots/.config/claude/skills/Tekton/workflows/TknCli.md
@@ -0,0 +1,690 @@
+# TknCli Workflow
+
+Tekton CLI (tkn) command reference and usage patterns for managing pipelines, tasks, and debugging.
+
+## When to Use
+
+- Running tkn commands
+- Viewing pipeline/task logs
+- Managing pipeline runs
+- Debugging Tekton workflows
+- Monitoring execution status
+
+## Installation
+
+### Package Managers
+
+```bash
+# macOS
+brew install tektoncd-cli
+
+# Windows
+choco install tektoncd-cli
+
+# Linux (deb-based)
+curl -LO https://github.com/tektoncd/cli/releases/download/v0.35.0/tektoncd-cli-0.35.0_Linux-64bit.deb
+sudo dpkg -i tektoncd-cli-0.35.0_Linux-64bit.deb
+
+# Linux (rpm-based)
+curl -LO https://github.com/tektoncd/cli/releases/download/v0.35.0/tektoncd-cli-0.35.0_Linux-64bit.rpm
+sudo rpm -Uvh tektoncd-cli-0.35.0_Linux-64bit.rpm
+
+# Linux (tarball)
+curl -LO https://github.com/tektoncd/cli/releases/download/v0.35.0/tkn_0.35.0_Linux_x86_64.tar.gz
+sudo tar xvzf tkn_0.35.0_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
+```
+
+### As kubectl Plugin
+
+```bash
+# Create symlink
+ln -s /usr/local/bin/tkn /usr/local/bin/kubectl-tkn
+
+# Use as kubectl plugin
+kubectl tkn version
+```
+
+### Shell Completion
+
+```bash
+# Bash
+source <(tkn completion bash)
+echo "source <(tkn completion bash)" >> ~/.bashrc
+
+# Zsh
+source <(tkn completion zsh)
+echo "source <(tkn completion zsh)" >> ~/.zshrc
+
+# Fish
+tkn completion fish | source
+echo "tkn completion fish | source" >> ~/.config/fish/config.fish
+```
+
+### Verify Installation
+
+```bash
+tkn version
+
+# Expected output:
+# Client version: 0.35.0
+# Pipeline version: v0.53.0
+# Triggers version: v0.25.0
+```
+
+## Pipeline Commands
+
+### List Pipelines
+
+```bash
+# List all pipelines
+tkn pipeline list
+
+# List with namespace
+tkn pipeline list -n <namespace>
+
+# List all namespaces
+tkn pipeline list --all-namespaces
+```
+
+### Describe Pipeline
+
+```bash
+# Show pipeline details
+tkn pipeline describe <pipeline-name>
+
+# Show with full YAML
+tkn pipeline describe <pipeline-name> -o yaml
+
+# Show with JSON
+tkn pipeline describe <pipeline-name> -o json
+```
+
+### Start Pipeline
+
+```bash
+# Start pipeline interactively
+tkn pipeline start <pipeline-name>
+
+# Start with parameters
+tkn pipeline start <pipeline-name> \
+ -p git-url=https://github.com/org/repo \
+ -p image-name=myregistry.com/myimage:latest
+
+# Start with workspace
+tkn pipeline start <pipeline-name> \
+ -w name=shared-data,claimName=my-pvc
+
+# Start with ServiceAccount
+tkn pipeline start <pipeline-name> \
+ --serviceaccount=pipeline-sa
+
+# Start and follow logs
+tkn pipeline start <pipeline-name> --showlog
+
+# Use last pipelinerun's parameters
+tkn pipeline start <pipeline-name> --last
+
+# Dry run (generate YAML without creating)
+tkn pipeline start <pipeline-name> \
+ -p git-url=https://github.com/org/repo \
+ --dry-run > pipelinerun.yaml
+```
+
+### Delete Pipeline
+
+```bash
+# Delete pipeline
+tkn pipeline delete <pipeline-name>
+
+# Delete without confirmation
+tkn pipeline delete <pipeline-name> -f
+
+# Delete all pipelines
+tkn pipeline delete --all
+
+# Delete with associated runs
+tkn pipeline delete <pipeline-name> --delete-prs
+```
+
+## PipelineRun Commands
+
+### List PipelineRuns
+
+```bash
+# List all pipelineruns
+tkn pipelinerun list
+
+# List for specific pipeline
+tkn pipelinerun list -p <pipeline-name>
+
+# List with timestamps
+tkn pipelinerun list -o wide
+
+# Limit results
+tkn pipelinerun list --limit 10
+```
+
+### Describe PipelineRun
+
+```bash
+# Describe last pipelinerun
+tkn pipelinerun describe --last
+
+# Describe specific pipelinerun
+tkn pipelinerun describe <pipelinerun-name>
+
+# Show full YAML
+tkn pipelinerun describe <pipelinerun-name> -o yaml
+
+# Show results
+tkn pipelinerun describe <pipelinerun-name> | grep -A 10 Results
+```
+
+### View Logs
+
+```bash
+# View logs from last pipelinerun
+tkn pipelinerun logs --last
+
+# Follow logs from last run
+tkn pipelinerun logs --last -f
+
+# View specific pipelinerun logs
+tkn pipelinerun logs <pipelinerun-name>
+
+# Follow specific pipelinerun
+tkn pipelinerun logs <pipelinerun-name> -f
+
+# View logs for specific task
+tkn pipelinerun logs <pipelinerun-name> -t <task-name>
+
+# View all task logs
+tkn pipelinerun logs <pipelinerun-name> --all
+
+# Stream logs with timestamps
+tkn pipelinerun logs --last -f --timestamps
+```
+
+### Cancel PipelineRun
+
+```bash
+# Cancel last pipelinerun
+tkn pipelinerun cancel --last
+
+# Cancel specific pipelinerun
+tkn pipelinerun cancel <pipelinerun-name>
+
+# Cancel without confirmation
+tkn pipelinerun cancel <pipelinerun-name> -f
+```
+
+### Delete PipelineRun
+
+```bash
+# Delete specific pipelinerun
+tkn pipelinerun delete <pipelinerun-name>
+
+# Delete last pipelinerun
+tkn pipelinerun delete --last
+
+# Delete all failed pipelineruns
+tkn pipelinerun delete --all -f --failed
+
+# Delete all pipelineruns for pipeline
+tkn pipelinerun delete --pipeline <pipeline-name>
+
+# Keep last N runs
+tkn pipelinerun delete --keep 5
+
+# Delete runs older than N minutes
+tkn pipelinerun delete --keep-since 60
+```
+
+## Task Commands
+
+### List Tasks
+
+```bash
+# List all tasks
+tkn task list
+
+# List in namespace
+tkn task list -n <namespace>
+
+# List all namespaces
+tkn task list --all-namespaces
+```
+
+### Describe Task
+
+```bash
+# Describe task
+tkn task describe <task-name>
+
+# Show YAML
+tkn task describe <task-name> -o yaml
+
+# Show parameters and workspaces
+tkn task describe <task-name> | grep -E "(Parameters|Workspaces)" -A 10
+```
+
+### Start Task
+
+```bash
+# Start task interactively
+tkn task start <task-name>
+
+# Start with parameters
+tkn task start <task-name> \
+ -p greeting=Hello \
+ -p name=World
+
+# Start with workspace
+tkn task start <task-name> \
+ -w name=source,claimName=my-pvc
+
+# Start and show logs
+tkn task start <task-name> --showlog
+
+# Use last taskrun's parameters
+tkn task start <task-name> --last
+```
+
+### Delete Task
+
+```bash
+# Delete task
+tkn task delete <task-name>
+
+# Delete without confirmation
+tkn task delete <task-name> -f
+
+# Delete with associated taskruns
+tkn task delete <task-name> --delete-trs
+```
+
+## TaskRun Commands
+
+### List TaskRuns
+
+```bash
+# List all taskruns
+tkn taskrun list
+
+# List for specific task
+tkn taskrun list -t <task-name>
+
+# List with details
+tkn taskrun list -o wide
+
+# Limit results
+tkn taskrun list --limit 10
+```
+
+### Describe TaskRun
+
+```bash
+# Describe last taskrun
+tkn taskrun describe --last
+
+# Describe specific taskrun
+tkn taskrun describe <taskrun-name>
+
+# Show YAML
+tkn taskrun describe <taskrun-name> -o yaml
+```
+
+### View TaskRun Logs
+
+```bash
+# View last taskrun logs
+tkn taskrun logs --last
+
+# Follow last taskrun
+tkn taskrun logs --last -f
+
+# View specific taskrun
+tkn taskrun logs <taskrun-name>
+
+# Follow specific taskrun
+tkn taskrun logs <taskrun-name> -f
+```
+
+### Delete TaskRun
+
+```bash
+# Delete taskrun
+tkn taskrun delete <taskrun-name>
+
+# Delete last taskrun
+tkn taskrun delete --last
+
+# Delete all taskruns
+tkn taskrun delete --all
+```
+
+## ClusterTask Commands (Deprecated)
+
+**IMPORTANT:** ClusterTasks are deprecated. Use resolvers instead.
+
+```bash
+# List clustertasks (still works but deprecated)
+tkn clustertask list
+
+# Describe clustertask
+tkn clustertask describe <clustertask-name>
+
+# Start clustertask
+tkn clustertask start <clustertask-name>
+```
+
+**Migration to resolvers:**
+```yaml
+# Old (ClusterTask)
+taskRef:
+ name: git-clone
+ kind: ClusterTask
+
+# New (Cluster resolver)
+taskRef:
+ resolver: cluster
+ params:
+ - name: name
+ value: git-clone
+ - name: namespace
+ value: tekton-tasks
+
+# Or use Hub resolver
+taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+```
+
+## Hub Commands
+
+### Search Hub
+
+```bash
+# Search for tasks
+tkn hub search git
+
+# Search with tags
+tkn hub search --tags git
+
+# Search with limit
+tkn hub search --limit 10
+```
+
+### Get Hub Task Info
+
+```bash
+# Get task info
+tkn hub info task git-clone
+
+# Get specific version
+tkn hub info task git-clone --version 0.10.0
+```
+
+### Install from Hub
+
+```bash
+# Install task from hub
+tkn hub install task git-clone
+
+# Install specific version
+tkn hub install task git-clone --version 0.10.0
+
+# Install to specific namespace
+tkn hub install task git-clone -n tekton-tasks
+```
+
+## Debugging Workflows
+
+### Check Pipeline Status
+
+```bash
+# Get overview
+tkn pipelinerun describe --last
+
+# Check task statuses
+tkn pipelinerun describe --last | grep "TASKRUNS"
+
+# View conditions
+kubectl get pipelinerun <name> -o jsonpath='{.status.conditions}'
+```
+
+### View Detailed Logs
+
+```bash
+# All task logs with timestamps
+tkn pipelinerun logs --last -f --all --timestamps
+
+# Specific task logs
+tkn pipelinerun logs --last -t <task-name> -f
+
+# Specific step logs (use kubectl)
+kubectl logs <pod-name> -c step-<step-name>
+```
+
+### Check Events
+
+```bash
+# View events for namespace
+kubectl get events --sort-by=.metadata.creationTimestamp
+
+# Filter for Tekton events
+kubectl get events | grep -E "(Task|Pipeline)"
+
+# Watch events
+kubectl get events -w
+```
+
+### Inspect Pods
+
+```bash
+# Find taskrun pods
+kubectl get pods | grep <pipelinerun-name>
+
+# Describe pod
+kubectl describe pod <pod-name>
+
+# Check init containers
+kubectl get pod <pod-name> -o jsonpath='{.spec.initContainers[*].name}'
+
+# Check step containers
+kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].name}'
+```
+
+### Debug Failed Tasks
+
+```bash
+# Describe failed taskrun
+tkn taskrun describe <taskrun-name>
+
+# View pod conditions
+kubectl get pod <pod-name> -o jsonpath='{.status.conditions}' | jq
+
+# Check step status
+kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses}' | jq
+
+# View terminated container info
+kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[?(@.name=="step-build")].state}' | jq
+```
+
+### Access Step Results
+
+```bash
+# View task results
+tkn taskrun describe <taskrun-name> | grep -A 10 "Results"
+
+# Get specific result
+kubectl get taskrun <name> -o jsonpath='{.status.taskResults[?(@.name=="commit-sha")].value}'
+```
+
+## Useful Aliases and Functions
+
+### Bash Aliases
+
+```bash
+# Add to ~/.bashrc
+
+alias tkn-logs='tkn pipelinerun logs --last -f'
+alias tkn-list='tkn pipelinerun list'
+alias tkn-desc='tkn pipelinerun describe --last'
+alias tkn-start='tkn pipeline start'
+alias tkn-cancel='tkn pipelinerun cancel --last'
+alias tkn-tasks='tkn taskrun list'
+alias tkn-clean='tkn pipelinerun delete --all -f'
+```
+
+### Bash Functions
+
+```bash
+# Add to ~/.bashrc
+
+# Follow logs for specific pipeline
+tkn-watch() {
+ tkn pipeline start "$1" --showlog
+}
+
+# Delete old pipelineruns
+tkn-prune() {
+ local keep=${1:-5}
+ tkn pipelinerun delete --keep $keep -f
+}
+
+# Get pipeline status
+tkn-status() {
+ tkn pipelinerun list | head -n 10
+}
+
+# Restart last failed pipeline
+tkn-retry() {
+ local last_pr=$(tkn pipelinerun list -o name | head -n 1 | cut -d'/' -f2)
+ tkn pipelinerun delete $last_pr -f
+ tkn pipeline start $(tkn pipelinerun describe $last_pr -o jsonpath='{.spec.pipelineRef.name}') --last
+}
+```
+
+## Common Workflows
+
+### Start Pipeline with Full Options
+
+```bash
+tkn pipeline start build-deploy \
+ -p git-url=https://github.com/myorg/myrepo \
+ -p git-revision=main \
+ -p image-name=myregistry.com/myapp:latest \
+ -w name=shared-data,volumeClaimTemplateFile=pvc-template.yaml \
+ --serviceaccount=pipeline-sa \
+ --showlog
+```
+
+### Monitor Pipeline Execution
+
+```bash
+# Start and follow logs
+tkn pipeline start my-pipeline --showlog
+
+# Or in separate commands
+tkn pipeline start my-pipeline
+tkn pipelinerun logs --last -f
+```
+
+### Cleanup Old Runs
+
+```bash
+# Keep last 5 runs
+tkn pipelinerun delete --keep 5 -f
+
+# Delete runs older than 60 minutes
+tkn pipelinerun delete --keep-since 60 -f
+
+# Delete all failed runs
+tkn pipelinerun delete --all --failed -f
+```
+
+### Export PipelineRun for Rerun
+
+```bash
+# Export last run as YAML
+tkn pipelinerun describe --last -o yaml > rerun.yaml
+
+# Edit if needed
+vim rerun.yaml
+
+# Remove status and metadata.name
+yq eval 'del(.status) | del(.metadata.name) | del(.metadata.namespace) | del(.metadata.uid)' rerun.yaml > clean-rerun.yaml
+
+# Apply
+kubectl apply -f clean-rerun.yaml
+```
+
+## Troubleshooting
+
+### tkn Command Not Found
+
+```bash
+# Check installation
+which tkn
+
+# Add to PATH if needed
+export PATH=$PATH:/usr/local/bin
+
+# Reinstall
+brew reinstall tektoncd-cli # macOS
+```
+
+### Cannot Connect to Cluster
+
+```bash
+# Check kubectl context
+kubectl config current-context
+
+# Check Tekton installation
+kubectl get pods -n tekton-pipelines
+
+# Check API access
+kubectl api-resources | grep tekton
+```
+
+### Logs Not Showing
+
+```bash
+# Check pod exists
+kubectl get pods | grep <pipelinerun-name>
+
+# Check pod status
+kubectl describe pod <pod-name>
+
+# Try kubectl logs directly
+kubectl logs <pod-name> -c step-<step-name>
+```
+
+### Permission Denied
+
+```bash
+# Check RBAC
+kubectl auth can-i create pipelineruns
+
+# Check ServiceAccount
+kubectl get serviceaccount
+
+# Check RoleBinding
+kubectl get rolebinding | grep tekton
+```
+
+## Best Practices
+
+- Always use `--showlog` or `-f` to follow pipeline execution
+- Set up shell completion for faster command entry
+- Use aliases for frequently used commands
+- Clean up old pipelineruns regularly to free resources
+- Use `--last` flag to avoid typing pipelinerun names
+- Export successful runs as templates for reuse
+- Monitor events during debugging (`kubectl get events -w`)
+- Use `tkn hub` to discover and install community tasks
dots/.config/claude/skills/Tekton/workflows/Triggers.md
@@ -0,0 +1,577 @@
+# Triggers Workflow
+
+Tekton Triggers for event-driven pipeline execution via webhooks and automated CI/CD.
+
+## When to Use
+
+- Setting up GitHub/GitLab webhooks
+- Automating pipeline execution from events
+- Creating event listeners
+- Configuring trigger bindings and templates
+- Integrating with version control systems
+
+## Trigger Components
+
+### EventListener
+
+**Listens for incoming HTTP events (webhooks)**
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: EventListener
+metadata:
+ name: github-listener
+spec:
+ serviceAccountName: tekton-triggers-sa
+ triggers:
+ - name: github-push
+ interceptors:
+ - ref:
+ name: "github"
+ params:
+ - name: "secretRef"
+ value:
+ secretName: github-secret
+ secretKey: secretToken
+ - name: "eventTypes"
+ value: ["push"]
+ bindings:
+ - ref: github-push-binding
+ template:
+ ref: pipeline-template
+```
+
+### TriggerBinding
+
+**Extracts data from event payload**
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: TriggerBinding
+metadata:
+ name: github-push-binding
+spec:
+ params:
+ - name: gitrevision
+ value: $(body.head_commit.id)
+ - name: gitrepositoryurl
+ value: $(body.repository.clone_url)
+ - name: gitbranch
+ value: $(body.ref)
+ - name: gitauthor
+ value: $(body.head_commit.author.username)
+ - name: gitmessage
+ value: $(body.head_commit.message)
+```
+
+### TriggerTemplate
+
+**Creates PipelineRun or TaskRun from event**
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: TriggerTemplate
+metadata:
+ name: pipeline-template
+spec:
+ params:
+ - name: gitrevision
+ description: Git commit SHA
+ - name: gitrepositoryurl
+ description: Repository URL
+ - name: gitbranch
+ description: Git branch ref
+ resourcetemplates:
+ - apiVersion: tekton.dev/v1
+ kind: PipelineRun
+ metadata:
+ generateName: ci-pipeline-run-
+ spec:
+ pipelineRef:
+ name: ci-pipeline
+ params:
+ - name: git-url
+ value: $(tt.params.gitrepositoryurl)
+ - name: git-revision
+ value: $(tt.params.gitrevision)
+ workspaces:
+ - name: source-code
+ volumeClaimTemplate:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+```
+
+## GitHub Integration
+
+### Complete GitHub Webhook Setup
+
+**1. Create Secret for Webhook Validation**
+
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: github-secret
+type: Opaque
+stringData:
+ secretToken: "your-webhook-secret-here"
+```
+
+**2. Create ServiceAccount with RBAC**
+
+```yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: tekton-triggers-sa
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: tekton-triggers-role
+rules:
+ - apiGroups: ["triggers.tekton.dev"]
+ resources: ["eventlisteners", "triggerbindings", "triggertemplates"]
+ verbs: ["get"]
+ - apiGroups: ["tekton.dev"]
+ resources: ["pipelineruns", "pipelineresources", "taskruns"]
+ verbs: ["create"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: tekton-triggers-binding
+subjects:
+ - kind: ServiceAccount
+ name: tekton-triggers-sa
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: tekton-triggers-role
+```
+
+**3. Create EventListener**
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: EventListener
+metadata:
+ name: github-listener
+spec:
+ serviceAccountName: tekton-triggers-sa
+ triggers:
+ - name: github-push
+ interceptors:
+ - ref:
+ name: "github"
+ params:
+ - name: "secretRef"
+ value:
+ secretName: github-secret
+ secretKey: secretToken
+ - name: "eventTypes"
+ value: ["push", "pull_request"]
+ bindings:
+ - ref: github-binding
+ template:
+ ref: pipeline-template
+```
+
+**4. Expose EventListener**
+
+```bash
+# Get event listener service
+kubectl get svc el-github-listener
+
+# Expose via Ingress
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: github-webhook
+ annotations:
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - webhooks.example.com
+ secretName: webhook-tls
+ rules:
+ - host: webhooks.example.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: el-github-listener
+ port:
+ number: 8080
+```
+
+**5. Configure GitHub Webhook**
+
+- Go to GitHub repository Settings → Webhooks
+- Payload URL: `https://webhooks.example.com`
+- Content type: `application/json`
+- Secret: Same value as in `github-secret`
+- Events: Push, Pull Request
+- Active: ✓
+
+### GitHub TriggerBinding Examples
+
+**Push event:**
+```yaml
+spec:
+ params:
+ - name: gitrevision
+ value: $(body.head_commit.id)
+ - name: gitrepositoryurl
+ value: $(body.repository.clone_url)
+ - name: gitbranch
+ value: $(extensions.branch_name)
+```
+
+**Pull Request event:**
+```yaml
+spec:
+ params:
+ - name: pr-number
+ value: $(body.pull_request.number)
+ - name: pr-title
+ value: $(body.pull_request.title)
+ - name: pr-head-sha
+ value: $(body.pull_request.head.sha)
+ - name: pr-base-branch
+ value: $(body.pull_request.base.ref)
+```
+
+## GitLab Integration
+
+### GitLab EventListener
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: EventListener
+metadata:
+ name: gitlab-listener
+spec:
+ serviceAccountName: tekton-triggers-sa
+ triggers:
+ - name: gitlab-push
+ interceptors:
+ - ref:
+ name: "gitlab"
+ params:
+ - name: "secretRef"
+ value:
+ secretName: gitlab-secret
+ secretKey: secretToken
+ - name: "eventTypes"
+ value: ["Push Hook", "Merge Request Hook"]
+ bindings:
+ - ref: gitlab-binding
+ template:
+ ref: pipeline-template
+```
+
+### GitLab TriggerBinding
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: TriggerBinding
+metadata:
+ name: gitlab-binding
+spec:
+ params:
+ - name: gitrevision
+ value: $(body.checkout_sha)
+ - name: gitrepositoryurl
+ value: $(body.project.git_http_url)
+ - name: gitbranch
+ value: $(body.ref)
+ - name: project-name
+ value: $(body.project.name)
+```
+
+## Interceptors
+
+### CEL Interceptor (Custom Logic)
+
+```yaml
+interceptors:
+ - name: "filter-branch"
+ ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.ref.startsWith('refs/heads/main')"
+ - name: "overlays"
+ value:
+ - key: branch_name
+ expression: "body.ref.split('/')[2]"
+```
+
+### Webhook Interceptor (Custom Service)
+
+```yaml
+interceptors:
+ - name: "custom-logic"
+ webhook:
+ objectRef:
+ apiVersion: v1
+ kind: Service
+ name: custom-interceptor
+ namespace: default
+ header:
+ - name: X-Custom-Header
+ value: "custom-value"
+```
+
+## Advanced Patterns
+
+### Multiple Triggers in One EventListener
+
+```yaml
+spec:
+ triggers:
+ - name: main-branch
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.ref == 'refs/heads/main'"
+ bindings:
+ - ref: prod-binding
+ template:
+ ref: prod-template
+
+ - name: feature-branch
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.ref.startsWith('refs/heads/feature/')"
+ bindings:
+ - ref: dev-binding
+ template:
+ ref: dev-template
+```
+
+### Conditional Pipeline Execution
+
+```yaml
+# In TriggerTemplate
+spec:
+ resourcetemplates:
+ - apiVersion: tekton.dev/v1
+ kind: PipelineRun
+ metadata:
+ generateName: conditional-run-
+ spec:
+ pipelineRef:
+ name: my-pipeline
+ params:
+ - name: deploy-to-prod
+ value: $(tt.params.gitbranch == "refs/heads/main")
+```
+
+### ClusterTriggerBinding (Cluster-Wide Reuse)
+
+```yaml
+apiVersion: triggers.tekton.dev/v1beta1
+kind: ClusterTriggerBinding
+metadata:
+ name: common-git-binding
+spec:
+ params:
+ - name: gitrevision
+ value: $(body.head_commit.id)
+ - name: gitrepositoryurl
+ value: $(body.repository.clone_url)
+```
+
+## Testing Triggers
+
+### Test with curl
+
+```bash
+# Get EventListener URL
+EL_URL=$(kubectl get eventlistener github-listener -o jsonpath='{.status.address.url}')
+
+# Send test payload
+curl -X POST $EL_URL \
+ -H "Content-Type: application/json" \
+ -H "X-GitHub-Event: push" \
+ -H "X-Hub-Signature: sha1=..." \
+ -d @test-payload.json
+
+# Watch for pipelinerun creation
+kubectl get pipelineruns -w
+```
+
+### Test Payload Examples
+
+**GitHub push:**
+```json
+{
+ "ref": "refs/heads/main",
+ "head_commit": {
+ "id": "abc123...",
+ "message": "Test commit",
+ "author": {
+ "username": "testuser"
+ }
+ },
+ "repository": {
+ "clone_url": "https://github.com/org/repo.git",
+ "name": "repo"
+ }
+}
+```
+
+## Troubleshooting
+
+### EventListener Not Receiving Events
+
+```bash
+# Check EventListener pod
+kubectl get pods -l eventlistener=github-listener
+
+# Check logs
+kubectl logs -l eventlistener=github-listener
+
+# Check service
+kubectl get svc el-github-listener
+
+# Test connectivity
+kubectl port-forward svc/el-github-listener 8080:8080
+curl -X POST http://localhost:8080 -d '{}'
+```
+
+### Webhook Validation Failing
+
+```bash
+# Check secret exists
+kubectl get secret github-secret
+
+# Verify secret value matches GitHub
+kubectl get secret github-secret -o jsonpath='{.data.secretToken}' | base64 -d
+
+# Check interceptor logs
+kubectl logs -l eventlistener=github-listener | grep "validation failed"
+```
+
+### PipelineRun Not Created
+
+```bash
+# Check EventListener logs
+kubectl logs -l eventlistener=github-listener
+
+# Check RBAC permissions
+kubectl auth can-i create pipelineruns --as=system:serviceaccount:default:tekton-triggers-sa
+
+# Check TriggerTemplate
+kubectl get triggertemplate pipeline-template -o yaml
+```
+
+### Wrong Parameters Extracted
+
+```bash
+# View received payload
+kubectl logs -l eventlistener=github-listener | grep "event body"
+
+# Test TriggerBinding
+# Create test EventListener with logging
+# Examine extracted parameters in logs
+```
+
+## Best Practices
+
+### Security
+- Always validate webhooks with secrets
+- Use HTTPS for webhook endpoints
+- Limit webhook events to necessary types
+- Use dedicated ServiceAccount with minimal permissions
+- Never expose raw event data in logs
+
+### Reliability
+- Set resource limits on EventListener pods
+- Use horizontal pod autoscaling for high traffic
+- Implement retry logic in pipelines
+- Monitor EventListener availability
+- Use Ingress with TLS termination
+
+### Maintainability
+- Use ClusterTriggerBinding for common parameters
+- Keep TriggerBindings focused and reusable
+- Document expected event payload structure
+- Version your TriggerTemplates
+- Use CEL interceptors for complex filtering
+
+### Performance
+- Filter events early with interceptors
+- Avoid creating unnecessary PipelineRuns
+- Use volumeClaimTemplate for workspace isolation
+- Set appropriate timeouts
+- Clean up old PipelineRuns with pruner
+
+## Common Patterns
+
+### Multi-Repository Trigger
+
+```yaml
+spec:
+ triggers:
+ - name: repo-a
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.repository.name == 'repo-a'"
+ template:
+ ref: repo-a-template
+
+ - name: repo-b
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.repository.name == 'repo-b'"
+ template:
+ ref: repo-b-template
+```
+
+### Branch-Based Pipeline Selection
+
+```yaml
+spec:
+ triggers:
+ - name: main-branch
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.ref == 'refs/heads/main'"
+ template:
+ ref: production-pipeline-template
+
+ - name: develop-branch
+ interceptors:
+ - ref:
+ name: "cel"
+ params:
+ - name: "filter"
+ value: "body.ref == 'refs/heads/develop'"
+ template:
+ ref: staging-pipeline-template
+```
dots/.config/claude/skills/Tekton/SKILL.md
@@ -0,0 +1,347 @@
+---
+name: Tekton
+description: Tekton Pipelines CI/CD best practices for Kubernetes-native workflows. USE WHEN working with Tekton tasks, pipelines, triggers, building container images, GitOps integration, or cloud-native CI/CD.
+---
+
+# Tekton
+
+Expert guidance on Tekton Pipelines, a Kubernetes-native CI/CD framework for building, testing, and deploying applications with declarative, reusable workflows.
+
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **Tekton** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **TknCli** | "tkn command", "view logs", "pipeline run", "task run" | `workflows/TknCli.md` |
+| **Tasks** | "create task", "task definition", "step", "taskrun" | `workflows/Tasks.md` |
+| **Pipelines** | "create pipeline", "pipeline workflow", "pipelinerun" | `workflows/Pipelines.md` |
+| **Triggers** | "webhook", "eventlistener", "trigger", "github integration" | `workflows/Triggers.md` |
+| **Build** | "build image", "kaniko", "buildah", "container build" | `workflows/Build.md` |
+| **GitOps** | "argocd", "flux", "gitops integration", "deployment automation" | `workflows/GitOps.md` |
+| **BestPractices** | "tekton best practices", "optimization", "security" | `workflows/BestPractices.md` |
+
+## Quick Reference
+
+### Essential tkn Commands
+
+```bash
+# Pipeline operations
+tkn pipeline list
+tkn pipeline describe <pipeline-name>
+tkn pipeline start <pipeline-name>
+tkn pipeline delete <pipeline-name>
+
+# PipelineRun operations
+tkn pipelinerun list
+tkn pipelinerun describe <pipelinerun-name>
+tkn pipelinerun logs <pipelinerun-name> -f
+tkn pipelinerun cancel <pipelinerun-name>
+tkn pipelinerun delete <pipelinerun-name>
+
+# Task operations
+tkn task list
+tkn task start <task-name>
+tkn taskrun logs <taskrun-name> -f
+
+# ClusterTask operations (deprecated - use resolvers)
+tkn clustertask list
+```
+
+### Common Aliases
+
+```bash
+alias tkn-logs='tkn pipelinerun logs --last -f'
+alias tkn-list='tkn pipelinerun list'
+alias tkn-desc='tkn pipelinerun describe --last'
+alias tkn-cancel='tkn pipelinerun cancel --last'
+```
+
+## Core Concepts
+
+### Tekton Building Blocks
+
+**Task**: Single unit of work with one or more Steps
+- Reusable, parameterized
+- Executes in containers
+- Can emit Results (<4KB)
+- Declares Workspace requirements
+
+**Pipeline**: Orchestrates multiple Tasks
+- Defines task execution order (sequential/parallel)
+- Manages data flow between tasks
+- DAG (Directed Acyclic Graph) execution
+
+**Trigger**: Event-driven pipeline execution
+- EventListener: Listens for webhooks
+- TriggerBinding: Extracts event data
+- TriggerTemplate: Creates PipelineRun/TaskRun
+
+**Workspace**: Shared filesystem storage
+- PersistentVolumeClaim (best for sharing)
+- emptyDir (temporary)
+- ConfigMap/Secret (configuration)
+
+### Task Example
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Task
+metadata:
+ name: hello-world
+spec:
+ params:
+ - name: greeting
+ description: The greeting message
+ default: "Hello"
+ steps:
+ - name: echo
+ image: alpine
+ script: |
+ echo "$(params.greeting), World!"
+```
+
+### Pipeline Example
+
+```yaml
+apiVersion: tekton.dev/v1
+kind: Pipeline
+metadata:
+ name: build-deploy
+spec:
+ params:
+ - name: git-url
+ - name: image-name
+ workspaces:
+ - name: shared-data
+ tasks:
+ - name: clone
+ taskRef:
+ name: git-clone
+ workspaces:
+ - name: output
+ workspace: shared-data
+ params:
+ - name: url
+ value: $(params.git-url)
+
+ - name: build
+ taskRef:
+ name: kaniko
+ runAfter:
+ - clone
+ workspaces:
+ - name: source
+ workspace: shared-data
+ params:
+ - name: IMAGE
+ value: $(params.image-name)
+```
+
+## Common Workflow Patterns
+
+### CI/CD Pipeline Pattern
+
+```
+1. Git Clone → Fetch source code
+2. Test → Run unit/integration tests
+3. Build → Build container image (Kaniko/Buildah)
+4. Scan → Security scan (Trivy)
+5. Push → Push to container registry
+6. Deploy → Update GitOps repo or deploy directly
+```
+
+### Task Execution Control
+
+**Sequential execution:**
+```yaml
+- name: build
+ runAfter:
+ - test
+```
+
+**Parallel execution:**
+```yaml
+- name: lint
+ # No runAfter - runs in parallel
+- name: test
+ # No runAfter - runs in parallel
+```
+
+**Conditional execution:**
+```yaml
+- name: deploy-prod
+ when:
+ - input: "$(params.environment)"
+ operator: in
+ values: ["production"]
+```
+
+**Cleanup (always runs):**
+```yaml
+finally:
+ - name: cleanup
+ taskRef:
+ name: cleanup-workspace
+```
+
+## Tekton Hub Integration
+
+**Reference tasks from Tekton Hub:**
+```yaml
+taskRef:
+ resolver: hub
+ params:
+ - name: name
+ value: git-clone
+ - name: version
+ value: "0.10.0"
+```
+
+**Popular Hub Tasks:**
+- `git-clone`: Clone Git repositories
+- `kaniko`: Build and push container images
+- `kubernetes-actions`: Run kubectl commands
+- `helm-upgrade`: Deploy Helm charts
+- `trivy-scanner`: Security scanning
+
+**Browse tasks:** https://hub.tekton.dev
+
+## Integration with Kubernetes Skill
+
+This Tekton skill builds on the Kubernetes skill:
+
+- **Kubernetes/Debug**: Debug pods created by Tekton TaskRuns
+- **Kubernetes/Deploy**: Understanding where Tekton deploys workloads
+- **Kubernetes/Resources**: Tekton creates Kubernetes CRDs (Tasks, Pipelines)
+- **Kubernetes/Security**: RBAC for Tekton ServiceAccounts
+- **Kubernetes/Context**: Managing Tekton across multiple clusters
+
+**Before using Tekton, ensure you're familiar with:**
+- Kubernetes pods and containers
+- PersistentVolumeClaims (PVCs)
+- ServiceAccounts and RBAC
+- Secrets and ConfigMaps
+- kubectl basics
+
+## Key Best Practices
+
+### Security
+- Use workspace-based authentication (not built-in credential init)
+- Create dedicated ServiceAccounts per pipeline
+- Follow least privilege principle for RBAC
+- Use personal access tokens, not passwords
+- Never commit secrets to Git
+
+### Performance
+- Always set resource requests/limits
+- Configure pipeline pruner for automatic cleanup
+- Use volumeClaimTemplate for isolation
+- Leverage caching (Kaniko layers, Maven deps)
+- Be aware of PVC access mode limitations
+
+### Reusability
+- Parameterize everything (no hardcoded values)
+- Use Tekton Hub tasks when available
+- Emit Results for small data (<4KB)
+- Use Workspaces for larger data
+- Keep tasks focused (single responsibility)
+
+### Anti-Patterns to Avoid
+1. **Don't use ClusterTasks** - Deprecated, use resolvers instead
+2. **Don't use PipelineResources** - Deprecated, use Tasks with Results
+3. **Don't skip resource limits** - Causes scheduling issues
+4. **Don't share ReadWriteOnce PVCs in parallel** - Will fail
+5. **Don't use built-in credential init only** - Moving to workspace-based auth
+6. **Don't create monolithic tasks** - Break into focused tasks
+7. **Don't ignore pipeline pruner** - Old resources fill etcd
+
+## Troubleshooting Quick Reference
+
+```bash
+# View pipeline run status
+tkn pipelinerun describe <name>
+
+# Stream logs
+tkn pipelinerun logs <name> -f
+
+# Check why task failed
+kubectl describe taskrun <taskrun-name>
+
+# View events
+kubectl get events --sort-by=.metadata.creationTimestamp
+
+# Check pod logs directly
+kubectl logs <pod-name> -c step-<step-name>
+
+# Debug container
+kubectl debug -it <pod-name> --image=alpine --target=<container>
+```
+
+## Examples
+
+**Example 1: Create CI pipeline**
+```
+User: "Create a Tekton pipeline that clones a repo, runs tests, and builds a container image"
+→ Invokes Pipelines workflow
+→ Creates pipeline with git-clone, test, and kaniko tasks
+→ Configures workspaces for source sharing
+→ Sets up proper task dependencies
+```
+
+**Example 2: Set up GitHub webhook**
+```
+User: "Set up GitHub webhook to trigger my pipeline on push"
+→ Invokes Triggers workflow
+→ Creates EventListener with GitHub interceptor
+→ Configures TriggerBinding to extract commit info
+→ Sets up TriggerTemplate to start PipelineRun
+```
+
+**Example 3: Integrate with ArgoCD**
+```
+User: "How do I integrate Tekton with ArgoCD for GitOps?"
+→ Invokes GitOps workflow
+→ Explains CI (Tekton) vs CD (ArgoCD) separation
+→ Shows how Tekton updates GitOps repo
+→ ArgoCD syncs changes to cluster
+```
+
+## Installation
+
+**Install Tekton Pipelines:**
+```bash
+kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
+```
+
+**Install Tekton Triggers:**
+```bash
+kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
+```
+
+**Install tkn CLI:**
+```bash
+# macOS
+brew install tektoncd-cli
+
+# Linux
+curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_<version>_Linux_x86_64.tar.gz
+sudo tar xvzf tkn_<version>_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
+```
+
+**Verify installation:**
+```bash
+kubectl get pods -n tekton-pipelines
+tkn version
+```
+
+## Related Skills
+
+- **Kubernetes**: Foundation for Tekton (pods, PVCs, RBAC)
+- **Git**: Source control integration and GitOps workflows
+- **Golang**: Writing custom Tekton tasks and controllers
+- **Nix/Homelab**: Managing Tekton in NixOS/K3s environments