# Automated deployment with Tekton
Take a real example Podinfo (opens new window) application and create full pipeline for it...
# Fork podinfo application
Fork the Podinfo (opens new window) repository
podinfo:
cd tmp
hub clone "stefanprodan/podinfo"
hub -C "podinfo" fork
Output:
Cloning into 'podinfo'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 5266 (delta 0), reused 3 (delta 0), pack-reused 5256
Receiving objects: 100% (5266/5266), 9.52 MiB | 1.93 MiB/s, done.
Resolving deltas: 100% (2342/2342), done.
Updating ruzickap
From https://github.com/stefanprodan/podinfo
* [new branch] gh-pages -> ruzickap/gh-pages
* [new branch] master -> ruzickap/master
* [new branch] v0.x -> ruzickap/v0.x
* [new branch] v1.x -> ruzickap/v1.x
* [new branch] v3.x -> ruzickap/v3.x
new remote: ruzickap
# Create Tekton Triggers configuration
Create new namespace:
kubectl create namespace getting-started
Create the admin user, role and rolebinding:
cat << EOF | kubectl apply -f -
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-admin
namespace: getting-started
rules:
- apiGroups:
- tekton.dev
resources:
- eventlisteners
- triggerbindings
- triggertemplates
- pipelineresources
verbs:
- get
- apiGroups:
- tekton.dev
resources:
- pipelineruns
- pipelineresources
verbs:
- create
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch
- create
- patch
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-admin
namespace: getting-started
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-admin-binding
namespace: getting-started
subjects:
- kind: ServiceAccount
name: tekton-triggers-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-admin
EOF
Create the create-webhook user, role and rolebinding:
cat << EOF | kubectl apply -f -
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-createwebhook
namespace: getting-started
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- create
- update
- delete
- apiGroups:
- tekton.dev
resources:
- eventlisteners
verbs:
- get
- list
- create
- update
- delete
- apiGroups:
- networking.istio.io
resources:
- virtualservices
- gateways
verbs:
- create
- get
- list
- delete
- update
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-createwebhook
namespace: getting-started
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-createwebhook
namespace: getting-started
subjects:
- kind: ServiceAccount
name: tekton-triggers-createwebhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-createwebhook
EOF
Create secret for Harbor registry to let Tekton pipeline to upload the container image:
kubectl create secret docker-registry -n getting-started harbor-docker-config \
--docker-server="${CONTAINER_REGISTRY_SERVER}" \
--docker-username="${CONTAINER_REGISTRY_USERNAME}" \
--docker-password="${CONTAINER_REGISTRY_PASSWORD}"
Install the Pipeline:
cat << \EOF | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: build-docker-image-from-git-task
namespace: getting-started
spec:
inputs:
resources:
- name: docker-source
type: git
params:
- name: pathToDockerFile
description: The path to the dockerfile to build
default: /workspace/docker-source/Dockerfile
- name: pathToContext
description:
The build context used by Kaniko
(https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
default: /workspace/docker-source
outputs:
resources:
- name: image-source
type: image
volumes:
- name: docker-config
secret:
secretName: harbor-docker-config
items:
- key: .dockerconfigjson
path: config.json
- name: shared-storage
emptyDir: {}
steps:
- name: build
image: gcr.io/kaniko-project/executor
env:
- name: "DOCKER_CONFIG"
value: "/builder/home/.docker/"
command:
- /kaniko/executor
args:
- --dockerfile=$(inputs.params.pathToDockerFile)
- --destination=$(outputs.resources.image-source.url)
- --context=$(inputs.params.pathToContext)
- --skip-tls-verify
volumeMounts:
- name: docker-config
mountPath: /builder/home/.docker/
---
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: deploy-locally
namespace: getting-started
spec:
inputs:
resources:
- name: image-source
type: image
outputs:
resources:
- name: event-to-sink
type: cloudEvent
steps:
- name: run-kubectl
image: lachlanevenson/k8s-kubectl:latest
command:
- sh
args:
- -ce
- |
set -ex
kubectl run podinfo --image $(inputs.resources.image-source.url) -o yaml --dry-run | kubectl apply -f -
---
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: getting-started-pipeline
namespace: getting-started
spec:
resources:
- name: docker-source
type: git
- name: image-source
type: image
- name: event-to-sink
type: cloudEvent
tasks:
- name: build-docker-image-from-git-task-run
taskRef:
name: build-docker-image-from-git-task
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/docker-source/
resources:
inputs:
- name: docker-source
resource: docker-source
outputs:
- name: image-source
resource: image-source
- name: deploy-locally
taskRef:
name: deploy-locally
resources:
inputs:
- name: image-source
resource: image-source
from:
- build-docker-image-from-git-task-run
outputs:
- name: event-to-sink
resource: event-to-sink
---
apiVersion: v1
kind: Service
metadata:
name: event-display
namespace: getting-started
labels:
app: event-display
spec:
type: ClusterIP
ports:
- name: listener
port: 8080
protocol: TCP
selector:
app: event-display
---
apiVersion: v1
kind: Pod
metadata:
name: event-display
namespace: getting-started
labels:
name: event-display
spec:
hostname: event-display
containers:
- image: gcr.io/knative-releases/github.com/knative/eventing-sources/cmd/event_display
name: web
EOF
Install the TriggerTemplate, TriggerBinding and EventListener:
cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: getting-started-triggertemplate
namespace: getting-started
spec:
params:
- name: gitrevision
description: The git revision
default: master
- name: gitrepositoryurl
description: The git repository url
- name: image_registry_url
description: The container registry url
- name: namespace
description: The namespace to create the resources
resourcetemplates:
- apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: source-repo-\$(uid)
namespace: \$(params.namespace)
spec:
type: git
params:
- name: revision
value: \$(params.gitrevision)
- name: url
value: \$(params.gitrepositoryurl)
- apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: image-source-\$(uid)
namespace: \$(params.namespace)
spec:
type: image
params:
- name: url
value: \$(params.image_registry_url)
- apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: event-to-sink-\$(uid)
namespace: \$(params.namespace)
spec:
type: cloudEvent
params:
- name: targetURI
value: http://event-display.getting-started.svc.cluster.local
- apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
name: getting-started-pipeline-run-\$(uid)
namespace: \$(params.namespace)
spec:
serviceAccount: tekton-triggers-admin
pipelineRef:
name: getting-started-pipeline
resources:
- name: docker-source
resourceRef:
name: source-repo-\$(uid)
- name: image-source
resourceRef:
name: image-source-\$(uid)
- name: event-to-sink
resourceRef:
name: event-to-sink-\$(uid)
---
apiVersion: tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: getting-started-pipelinebinding
namespace: getting-started
spec:
params:
- name: gitrevision
value: \$(body.head_commit.id)
- name: namespace
value: getting-started
- name: gitrepositoryurl
value: "https://github.com/\$(body.repository.full_name)"
- name: image_registry_url
value: "harbor.${MY_DOMAIN}/library/\$(body.repository.name)"
---
apiVersion: tekton.dev/v1alpha1
kind: EventListener
metadata:
name: getting-started-listener
namespace: getting-started
spec:
serviceAccountName: tekton-triggers-admin
triggers:
- binding:
name: getting-started-pipelinebinding
template:
name: getting-started-triggertemplate
EOF
# Configure webhook
Create Task which will create Istio Gateway and VirtualService to handle incoming webhook form GitHub:
cat << \EOF2 | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: create-istio-gateway-virtualservice
namespace: getting-started
spec:
volumes:
- name: work
emptyDir: {}
inputs:
params:
- name: TLScredentialName
description: "Specify the secret with wildcard certificate"
- name: ExternalDomain
description: "The external domain for the EventListener"
- name: Service
description: "The name of the Service used in the VirtualService"
- name: ServicePort
description: "The service port that the VirtualService is being created on"
steps:
- name: create-istio-gateway-virtualservice
image: lachlanevenson/k8s-kubectl:latest
command:
- sh
args:
- -ce
- |
set -ex
cat << EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: $(inputs.params.Service)-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https-$(inputs.params.Service)
protocol: HTTPS
hosts:
- $(inputs.params.ExternalDomain)
tls:
credentialName: $(inputs.params.TLScredentialName)
mode: SIMPLE
privateKey: sds
serverCertificate: sds
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: $(inputs.params.Service)-virtual-service
spec:
hosts:
- $(inputs.params.ExternalDomain)
gateways:
- $(inputs.params.Service)-gateway
http:
- route:
- destination:
host: $(inputs.params.Service)
port:
number: $(inputs.params.ServicePort)
EOF
EOF2
Create TaskRun to start create-istio-gateway-virtualservice Task:
cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: create-istio-gateway-virtualservice-run
namespace: getting-started
spec:
taskRef:
name: create-istio-gateway-virtualservice
inputs:
params:
- name: TLScredentialName
value: ingress-cert-${LETSENCRYPT_ENVIRONMENT}
- name: ExternalDomain
value: getting-started.${MY_DOMAIN}
- name: Service
value: el-getting-started-listener
- name: ServicePort
value: "8080"
timeout: 1000s
serviceAccount: tekton-triggers-createwebhook
EOF
Create webhook Task:
cat << \EOF | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: create-webhook
namespace: getting-started
spec:
volumes:
- name: github-secret
secret:
secretName: $(inputs.params.GitHubSecretName)
inputs:
params:
- name: ExternalDomain
description: "The external domain for the EventListener e.g. `$(inputs.params.EventListenerName).<PROXYIP>.nip.io`"
- name: GitHubUser
description: "The GitHub user"
- name: GitHubRepo
description: "The GitHub repo where the webhook will be created"
- name: GitHubOrg
description: "The GitHub organization where the webhook will be created"
- name: GitHubSecretName
description: "The Secret name for GitHub access token. This is always mounted and must exist"
- name: GitHubAccessTokenKey
description: "The GitHub access token key name"
- name: GitHubSecretStringKey
description: "The GitHub secret string key name"
- name: GitHubDomain
description: "The GitHub domain. Override for GitHub Enterprise"
default: "github.com"
- name: WebhookEvents
description: "List of events the webhook will send notifications for"
default: "[\\\"push\\\",\\\"pull_request\\\"]"
steps:
- name: create-webhook
image: pstauffer/curl:latest
volumeMounts:
- name: github-secret
mountPath: /var/secret
command:
- sh
args:
- -ce
- |
set -e
echo "Create Webhook"
if [ $(inputs.params.GitHubDomain) = "github.com" ];then
curl -v -d "{\"name\": \"web\",\"active\": true,\"events\": $(inputs.params.WebhookEvents),\"config\": {\"url\": \"https://$(inputs.params.ExternalDomain)\",\"content_type\": \"json\",\"insecure_ssl\": \"1\" ,\"secret\": \"$(cat /var/secret/$(inputs.params.GitHubSecretStringKey))\"}}" -X POST -u $(inputs.params.GitHubUser):$(cat /var/secret/$(inputs.params.GitHubAccessTokenKey)) -L https://api.github.com/repos/$(inputs.params.GitHubOrg)/$(inputs.params.GitHubRepo)/hooks
else
curl -d "{\"name\": \"web\",\"active\": true,\"events\": $(inputs.params.WebhookEvents),\"config\": {\"url\": \"https://$(inputs.params.ExternalDomain)/\",\"content_type\": \"json\",\"insecure_ssl\": \"1\" ,\"secret\": \"$(cat /var/secret/$(inputs.params.GitHubSecretStringKey))\"}}" -X POST -u $(inputs.params.GitHubUser):$(cat /var/secret/$(inputs.params.GitHubAccessTokenKey)) -L https://$(inputs.params.GitHubDomain)/api/v3/repos/$(inputs.params.GitHubOrg)/$(inputs.params.GitHubRepo)/hooks
fi
EOF
Create secret with GitHub Personal Access Token (opens new window):
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: webhook-secret
namespace: getting-started
stringData:
token: ${GITHUB_TOKEN}
secret: random-string-data
EOF
Create TaskRun to initiate Webhook:
sleep 20 # Wait for DNS created by previous TaskRun
cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: create-webhook-run
namespace: getting-started
spec:
taskRef:
name: create-webhook
inputs:
params:
- name: GitHubOrg
value: "ruzickap"
- name: GitHubUser
value: "ruzickap"
- name: GitHubRepo
value: "podinfo"
- name: GitHubSecretName
value: webhook-secret
- name: GitHubAccessTokenKey
value: token
- name: GitHubSecretStringKey
value: secret
- name: ExternalDomain
value: getting-started.${MY_DOMAIN}
timeout: 1000s
serviceAccount: tekton-triggers-createwebhook
EOF
sleep 5
Verify if the TaskRuns were successfully executed:
kubectl get taskruns.tekton.dev -n getting-started
Output:
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
create-istio-gateway-virtualservice-run True Succeeded 80s 71s
create-webhook-run Unknown Pending 2s
Look at the logs from create-istio-gateway-virtualservice TaskRun:
tkn taskrun logs -n getting-started create-istio-gateway-virtualservice-run
Output:
[create-istio-gateway-virtualservice] + + kubectl create -f -
[create-istio-gateway-virtualservice] cat
[create-istio-gateway-virtualservice] gateway.networking.istio.io/el-getting-started-listener-gateway created
[create-istio-gateway-virtualservice] virtualservice.networking.istio.io/el-getting-started-listener-virtual-service created
Look at the logs from create-webhook-run TaskRun:
tkn taskrun logs -n getting-started create-webhook-run
Output:
[create-webhook] Create Webhook
[create-webhook] Note: Unnecessary use of -X or --request, POST is already inferred.
[create-webhook] % Total % Received % Xferd Average Speed Time Time Time Current
[create-webhook] Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 140.82.118.6...
[create-webhook] * TCP_NODELAY set
[create-webhook] * Connected to api.github.com (140.82.118.6) port 443 (#0)
[create-webhook] * ALPN, offering h2
[create-webhook] * ALPN, offering http/1.1
[create-webhook] * successfully set certificate verify locations:
[create-webhook] * CAfile: /etc/ssl/certs/ca-certificates.crt
[create-webhook] CApath: none
[create-webhook] * TLSv1.2 (OUT), TLS handshake, Client hello (1):
[create-webhook] } [232 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS handshake, Server hello (2):
[create-webhook] { [108 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS handshake, Certificate (11):
[create-webhook] { [2851 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
[create-webhook] { [300 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS handshake, Server finished (14):
[create-webhook] { [4 bytes data]
[create-webhook] * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
[create-webhook] } [37 bytes data]
[create-webhook] * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
[create-webhook] } [1 bytes data]
[create-webhook] * TLSv1.2 (OUT), TLS handshake, Finished (20):
[create-webhook] } [16 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS change cipher, Client hello (1):
[create-webhook] { [1 bytes data]
[create-webhook] * TLSv1.2 (IN), TLS handshake, Finished (20):
[create-webhook] { [16 bytes data]
[create-webhook] * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
[create-webhook] * ALPN, server accepted to use http/1.1
[create-webhook] * Server certificate:
[create-webhook] * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=*.github.com
[create-webhook] * start date: Jul 8 00:00:00 2019 GMT
[create-webhook] * expire date: Jul 16 12:00:00 2020 GMT
[create-webhook] * subjectAltName: host "api.github.com" matched cert's "*.github.com"
[create-webhook] * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
[create-webhook] * SSL certificate verify ok.
[create-webhook] * Server auth using Basic with user 'ruzickap'
[create-webhook] > POST /repos/ruzickap/podinfo/hooks HTTP/1.1
[create-webhook] > Host: api.github.com
[create-webhook] > Authorization: Basic cnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxU3MA==
[create-webhook] > User-Agent: curl/7.60.0
[create-webhook] > Accept: */*
[create-webhook] > Content-Length: 195
[create-webhook] > Content-Type: application/x-www-form-urlencoded
[create-webhook] >
[create-webhook] } [195 bytes data]
[create-webhook] * upload completely sent off: 195 out of 195 bytes
[create-webhook] < HTTP/1.1 201 Created
[create-webhook] < Date: Fri, 27 Dec 2019 10:19:37 GMT
[create-webhook] < Content-Type: application/json; charset=utf-8
[create-webhook] < Content-Length: 688
[create-webhook] < Server: GitHub.com
[create-webhook] < Status: 201 Created
[create-webhook] < X-RateLimit-Limit: 5000
[create-webhook] < X-RateLimit-Remaining: 4992
[create-webhook] < X-RateLimit-Reset: 1577445296
[create-webhook] < Cache-Control: private, max-age=60, s-maxage=60
[create-webhook] < Vary: Accept, Authorization, Cookie, X-GitHub-OTP
[create-webhook] < ETag: "a9xxxxxxxxxxxxxxxxxxxxxxxxxxxxe3"
[create-webhook] < X-OAuth-Scopes: admin:org_hook, admin:repo_hook, delete_repo, read:org, repo, user:email
[create-webhook] < X-Accepted-OAuth-Scopes: admin:repo_hook, public_repo, repo, write:repo_hook
[create-webhook] < Location: https://api.github.com/repos/ruzickap/podinfo/hooks/170061618
[create-webhook] < X-GitHub-Media-Type: github.v3; format=json
[create-webhook] < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type
[create-webhook] < Access-Control-Allow-Origin: *
[create-webhook] < Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
[create-webhook] < X-Frame-Options: deny
[create-webhook] < X-Content-Type-Options: nosniff
[create-webhook] < X-XSS-Protection: 1; mode=block
[create-webhook] < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
[create-webhook] < Content-Security-Policy: default-src 'none'
[create-webhook] < Vary: Accept-Encoding
[create-webhook] < X-GitHub-Request-Id: CEXX:XXXXX:XXXXXXX:XXXXXXX:XXXXXXB9
[create-webhook] <
[create-webhook] { [688 bytes data]
100 883 100 688 100 195 1746 494 --:--:-- --:--:-- --:--:-- 2241
[create-webhook] * Connection #0 to host api.github.com left intact
[create-webhook] {
[create-webhook] "type": "Repository",
[create-webhook] "id": 170061618,
[create-webhook] "name": "web",
[create-webhook] "active": true,
[create-webhook] "events": [
[create-webhook] "pull_request",
[create-webhook] "push"
[create-webhook] ],
[create-webhook] "config": {
[create-webhook] "content_type": "json",
[create-webhook] "insecure_ssl": "1",
[create-webhook] "secret": "********",
[create-webhook] "url": "https://getting-started.mylabs.dev"
[create-webhook] },
[create-webhook] "updated_at": "2019-12-27T10:19:37Z",
[create-webhook] "created_at": "2019-12-27T10:19:37Z",
[create-webhook] "url": "https://api.github.com/repos/ruzickap/podinfo/hooks/170061618",
[create-webhook] "test_url": "https://api.github.com/repos/ruzickap/podinfo/hooks/170061618/test",
[create-webhook] "ping_url": "https://api.github.com/repos/ruzickap/podinfo/hooks/170061618/pings",
[create-webhook] "last_response": {
[create-webhook] "code": null,
[create-webhook] "status": "unused",
[create-webhook] "message": null
[create-webhook] }
[create-webhook] }
You should also see in the GitHub / Settings / Webhook the registration https://github.com/ruzickap/podinfo/settings/hooks/ (opens new window):

After clicking on the Webhook you can see the details:

In case you are troubleshooting the incoming traffic from GitHub the look at
the logs of the pod. You should be able to see the details
in the kubectl logs.
kubectl get pods -n getting-started -l eventlistener=getting-started-listener
sleep 5
Output:
NAME READY STATUS RESTARTS AGE
el-getting-started-listener-fcffc467d-xwsfp 1/1 Running 0 2m6s
# Change the source code of the app
Trigger the pipeline by calling the:
echo "Trigger build" >> podinfo/README.md
git -C podinfo commit -s -a -m "Standard version"
git -C podinfo push ruzickap
sleep 30
kubectl --timeout=10m -n getting-started wait --for=condition=Succeeded pipelineruns --all
sleep 5
Output:
[master d4120e6] Standard version
1 file changed, 1 insertion(+), 1 deletion(-)
Warning: Permanently added '[ssh.github.com]:443,[192.30.253.122]:443' (RSA) to the list of known hosts.
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 325 bytes | 162.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:ruzickap/podinfo.git
948de81..d4120e6 master -> master
pipelinerun.tekton.dev/getting-started-pipeline-run-fzrtg condition met
Look at the logs of the newly deployed pod (look at "Starting podinfo"):
PODINFO_POD=$(kubectl get pods -n getting-started -l=run=podinfo -o jsonpath="{.items[0].metadata.name}")
kubectl -n getting-started logs -n getting-started ${PODINFO_POD}
Output:
{"level":"info","ts":"2019-11-27T15:00:58.907Z","caller":"podinfo/main.go:120","msg":"Starting podinfo","version":"3.1.5","revision":"164a27b33b09d1b50fad277a60a6c19d353cb9d8","port":"9898"}
Let's try to change the code of the application:
sed -i "s/Starting podinfo/Starting podinfo - new Tekton build version/" podinfo/cmd/podinfo/main.go
git -C podinfo diff
git -C podinfo commit -s -a -m "String changed"
git -C podinfo push ruzickap
sleep 20
Output:
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
modified: cmd/podinfo/main.go
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
@ cmd/podinfo/main.go:120 @ func main() {
}
// log version and port
logger.Info("Starting podinfo",
logger.Info("Starting podinfo - new Tekton build version",
zap.String("version", viper.GetString("version")),
zap.String("revision", viper.GetString("revision")),
zap.String("port", srvCfg.Port),
[master 4d9f5bc] String changed
1 file changed, 1 insertion(+), 1 deletion(-)
Warning: Permanently added '[ssh.github.com]:443,[192.30.253.122]:443' (RSA) to the list of known hosts.
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 459 bytes | 459.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:ruzickap/podinfo.git
d4120e6..4d9f5bc master -> master
Wait for the pipelines to complete:
kubectl --timeout=10m -n getting-started wait --for=condition=Succeeded pipelineruns --all
sleep 5
Output:
pipelinerun.tekton.dev/getting-started-pipeline-run-dzqdl condition met
pipelinerun.tekton.dev/getting-started-pipeline-run-fzrtg condition met
Check how the logs of the newly deployed podinfo logs should contain "Starting podinfo - new Tekton build version":
PODINFO_POD=$(kubectl get pods -n getting-started -l=run=podinfo -o jsonpath="{.items[0].metadata.name}")
kubectl -n getting-started delete pod -n getting-started ${PODINFO_POD}
sleep 5
PODINFO_POD=$(kubectl get pods -n getting-started -l=run=podinfo -o jsonpath="{.items[0].metadata.name}")
kubectl -n getting-started logs -n getting-started ${PODINFO_POD}
cd ..
Output:
pod "podinfo-6ccfb5f9b6-bwrbn" deleted
{"level":"info","ts":"2019-12-27T10:28:22.304Z","caller":"podinfo/main.go:120","msg":"Starting podinfo - new Tekton build version","version":"3.1.5","revision":"4d9f5bc71bd9a8c7ae44a9cd9631e45067727a2e","port":"9898"}