From a31b2b1a5597ae6e4ab66f58a9833078c09b8b6c Mon Sep 17 00:00:00 2001 From: Mayne0213 Date: Wed, 7 Jan 2026 16:30:22 +0900 Subject: [PATCH] FEAT(tekton): add Tekton Triggers for GitHub webhooks - Add EventListener for GitHub push events - Add TriggerBinding for payload parsing - Add TriggerTemplates for Next.js and FastAPI - Add RBAC for trigger service account - Add ExternalSecret for webhook secret from Vault - Add Ingress at tekton0213.kro.kr/hooks --- tekton/ci-cd/manifests/kustomization.yaml | 2 + .../manifests/triggers/eventlistener.yaml | 79 +++++++++++++ tekton/ci-cd/manifests/triggers/ingress.yaml | 24 ++++ .../manifests/triggers/kustomization.yaml | 10 ++ tekton/ci-cd/manifests/triggers/rbac.yaml | 60 ++++++++++ tekton/ci-cd/manifests/triggers/secret.yaml | 18 +++ .../manifests/triggers/triggerbinding.yaml | 17 +++ .../manifests/triggers/triggertemplate.yaml | 105 ++++++++++++++++++ 8 files changed, 315 insertions(+) create mode 100644 tekton/ci-cd/manifests/triggers/eventlistener.yaml create mode 100644 tekton/ci-cd/manifests/triggers/ingress.yaml create mode 100644 tekton/ci-cd/manifests/triggers/kustomization.yaml create mode 100644 tekton/ci-cd/manifests/triggers/rbac.yaml create mode 100644 tekton/ci-cd/manifests/triggers/secret.yaml create mode 100644 tekton/ci-cd/manifests/triggers/triggerbinding.yaml create mode 100644 tekton/ci-cd/manifests/triggers/triggertemplate.yaml diff --git a/tekton/ci-cd/manifests/kustomization.yaml b/tekton/ci-cd/manifests/kustomization.yaml index 0d11a8e..1ac4ae0 100644 --- a/tekton/ci-cd/manifests/kustomization.yaml +++ b/tekton/ci-cd/manifests/kustomization.yaml @@ -12,3 +12,5 @@ resources: - pipelines/nextjs-pipeline.yaml - pipelines/fastapi-pipeline.yaml - pipelines/python-pipeline.yaml + # Triggers + - triggers/ diff --git a/tekton/ci-cd/manifests/triggers/eventlistener.yaml b/tekton/ci-cd/manifests/triggers/eventlistener.yaml new file mode 100644 index 0000000..708680a --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/eventlistener.yaml @@ -0,0 +1,79 @@ +apiVersion: triggers.tekton.dev/v1beta1 +kind: EventListener +metadata: + name: github-listener + namespace: tekton-pipelines +spec: + serviceAccountName: tekton-triggers-sa + triggers: + - name: github-push-nextjs + interceptors: + - ref: + name: "github" + params: + - name: "secretRef" + value: + secretName: github-webhook-secret + secretKey: webhook-secret + - name: "eventTypes" + value: ["push"] + - ref: + name: "cel" + params: + - name: "filter" + value: "body.ref.startsWith('refs/heads/main')" + - name: "overlays" + value: + - key: branch_name + expression: "body.ref.split('/')[2]" + - ref: + name: "cel" + params: + - name: "filter" + value: "body.repository.name in ['jovies', 'jotion', 'jaejadle', 'portfolio', 'todo']" + bindings: + - ref: github-push-binding + template: + ref: nextjs-build-template + - name: github-push-fastapi + interceptors: + - ref: + name: "github" + params: + - name: "secretRef" + value: + secretName: github-webhook-secret + secretKey: webhook-secret + - name: "eventTypes" + value: ["push"] + - ref: + name: "cel" + params: + - name: "filter" + value: "body.ref.startsWith('refs/heads/main')" + - name: "overlays" + value: + - key: branch_name + expression: "body.ref.split('/')[2]" + - ref: + name: "cel" + params: + - name: "filter" + value: "body.repository.name in ['joossam', 'mas']" + bindings: + - ref: github-push-binding + template: + ref: fastapi-build-template + resources: + kubernetesResource: + spec: + template: + spec: + serviceAccountName: tekton-triggers-sa + containers: + - resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" diff --git a/tekton/ci-cd/manifests/triggers/ingress.yaml b/tekton/ci-cd/manifests/triggers/ingress.yaml new file mode 100644 index 0000000..330ee31 --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/ingress.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tekton-triggers-ingress + namespace: tekton-pipelines + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" +spec: + ingressClassName: traefik + tls: + - hosts: + - tekton0213.kro.kr + secretName: tekton-triggers-tls + rules: + - host: tekton0213.kro.kr + http: + paths: + - path: /hooks + pathType: Prefix + backend: + service: + name: el-github-listener + port: + number: 8080 diff --git a/tekton/ci-cd/manifests/triggers/kustomization.yaml b/tekton/ci-cd/manifests/triggers/kustomization.yaml new file mode 100644 index 0000000..bf9c57e --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - rbac.yaml + - secret.yaml + - triggerbinding.yaml + - triggertemplate.yaml + - eventlistener.yaml + - ingress.yaml diff --git a/tekton/ci-cd/manifests/triggers/rbac.yaml b/tekton/ci-cd/manifests/triggers/rbac.yaml new file mode 100644 index 0000000..80f8d8b --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/rbac.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: tekton-triggers-sa + namespace: tekton-pipelines +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: tekton-triggers-role + namespace: tekton-pipelines +rules: + - apiGroups: ["triggers.tekton.dev"] + resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers", "interceptors"] + verbs: ["get", "list", "watch"] + - apiGroups: ["tekton.dev"] + resources: ["pipelineruns", "pipelineresources"] + verbs: ["create", "delete", "get", "list", "watch"] + - apiGroups: [""] + resources: ["configmaps", "secrets", "serviceaccounts"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["create", "delete", "get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: tekton-triggers-rolebinding + namespace: tekton-pipelines +subjects: + - kind: ServiceAccount + name: tekton-triggers-sa + namespace: tekton-pipelines +roleRef: + kind: Role + name: tekton-triggers-role + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: tekton-triggers-clusterrole +rules: + - apiGroups: ["triggers.tekton.dev"] + resources: ["clustertriggerbindings", "clusterinterceptors"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: tekton-triggers-clusterrolebinding +subjects: + - kind: ServiceAccount + name: tekton-triggers-sa + namespace: tekton-pipelines +roleRef: + kind: ClusterRole + name: tekton-triggers-clusterrole + apiGroup: rbac.authorization.k8s.io diff --git a/tekton/ci-cd/manifests/triggers/secret.yaml b/tekton/ci-cd/manifests/triggers/secret.yaml new file mode 100644 index 0000000..1bf0cea --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/secret.yaml @@ -0,0 +1,18 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: github-webhook-secret + namespace: tekton-pipelines +spec: + refreshInterval: 1h + secretStoreRef: + name: vault-backend + kind: ClusterSecretStore + target: + name: github-webhook-secret + creationPolicy: Owner + data: + - secretKey: webhook-secret + remoteRef: + key: tekton + property: GITHUB_WEBHOOK_SECRET diff --git a/tekton/ci-cd/manifests/triggers/triggerbinding.yaml b/tekton/ci-cd/manifests/triggers/triggerbinding.yaml new file mode 100644 index 0000000..760b1b0 --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/triggerbinding.yaml @@ -0,0 +1,17 @@ +apiVersion: triggers.tekton.dev/v1beta1 +kind: TriggerBinding +metadata: + name: github-push-binding + namespace: tekton-pipelines +spec: + params: + - name: git-url + value: $(body.repository.clone_url) + - name: git-revision + value: $(body.after) + - name: git-branch + value: $(extensions.branch_name) + - name: repo-name + value: $(body.repository.name) + - name: repo-full-name + value: $(body.repository.full_name) diff --git a/tekton/ci-cd/manifests/triggers/triggertemplate.yaml b/tekton/ci-cd/manifests/triggers/triggertemplate.yaml new file mode 100644 index 0000000..17d9a9e --- /dev/null +++ b/tekton/ci-cd/manifests/triggers/triggertemplate.yaml @@ -0,0 +1,105 @@ +apiVersion: triggers.tekton.dev/v1beta1 +kind: TriggerTemplate +metadata: + name: nextjs-build-template + namespace: tekton-pipelines +spec: + params: + - name: git-url + description: Git repository URL + - name: git-revision + description: Git commit SHA + - name: git-branch + description: Git branch name + - name: repo-name + description: Repository name + - name: repo-full-name + description: Full repository name (org/repo) + resourcetemplates: + - apiVersion: tekton.dev/v1 + kind: PipelineRun + metadata: + generateName: $(tt.params.repo-name)-build- + namespace: tekton-pipelines + labels: + tekton.dev/pipeline: nextjs-build-deploy + app: $(tt.params.repo-name) + branch: $(tt.params.git-branch) + spec: + pipelineRef: + name: nextjs-build-deploy + params: + - name: git-url + value: $(tt.params.git-url) + - name: git-revision + value: $(tt.params.git-branch) + - name: app-name + value: $(tt.params.repo-name) + - name: context-dir + value: ./nextjs + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: 1Gi + - name: docker-credentials + secret: + secretName: zot-registry-credentials +--- +apiVersion: triggers.tekton.dev/v1beta1 +kind: TriggerTemplate +metadata: + name: fastapi-build-template + namespace: tekton-pipelines +spec: + params: + - name: git-url + description: Git repository URL + - name: git-revision + description: Git commit SHA + - name: git-branch + description: Git branch name + - name: repo-name + description: Repository name + - name: repo-full-name + description: Full repository name (org/repo) + resourcetemplates: + - apiVersion: tekton.dev/v1 + kind: PipelineRun + metadata: + generateName: $(tt.params.repo-name)-build- + namespace: tekton-pipelines + labels: + tekton.dev/pipeline: fastapi-build-deploy + app: $(tt.params.repo-name) + branch: $(tt.params.git-branch) + spec: + pipelineRef: + name: fastapi-build-deploy + params: + - name: git-url + value: $(tt.params.git-url) + - name: git-revision + value: $(tt.params.git-branch) + - name: app-name + value: $(tt.params.repo-name) + - name: context-dir + value: ./fastapi + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: 1Gi + - name: docker-credentials + secret: + secretName: zot-registry-credentials