making / jaguchi-manifests

1 stars 11 forks source link

Naomiはsource-to-urlの前にunit testを実行したい #19

Closed making closed 2 years ago

making commented 2 years ago

Why

As Naomi I want to コンテナイメージビルドの前にテストを実行したい So that テストが通っていないソースをデプロイしたくないから

Acceptance Criteria

Scenario: 
Given テストコードが失敗する
When コードをコミットしたら
Then テストが実行され、失敗してコンテナイメージが作成されない
Scenario: 
Given テストコードが成功する
When コードをコミットしたら
Then テストが実行され、その後コンテナイメージが作成され、デプロイされる

Notes:

making commented 2 years ago

https://github.com/tanzu-japan/jaguchi-manifests/commit/e7f9eb32bb11cbb9c2d3775cd526a386ded68838

$ kubectl get clustersupplychain
NAME                 READY   REASON   AGE
basic-image-to-url   True    Ready    25d
source-test-to-url   True    Ready    11m
source-to-url        True    Ready    25d
making commented 2 years ago

Maven用のPipeline

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: developer-defined-tekton-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test      # (!) required
spec:
  params:
    - name: source-url                        # (!) required
    - name: source-revision                   # (!) required
  tasks:
    - name: test
      params:
        - name: source-url
          value: $(params.source-url)
        - name: source-revision
          value: $(params.source-revision)
      taskSpec:
        params:
          - name: source-url
          - name: source-revision
        steps:
          - name: test
            image: eclipse-temurin:17
            script: |-
              set -ex
              cd `mktemp -d`
              curl -s $(params.source-url) | tar -xzvf -
              ./mvnw clean test -V --no-transfer-progress
kubectl apply -f pipeline.yaml

これで

tanzu apps workload apply hello-servlet \
  --app hello-servlet \
  --git-repo https://github.com/making/hello-servlet \
  --git-branch master \
  --type web \
  --label apps.tanzu.vmware.com/has-tests=true \
  -n ${NAMESPACE} -y
tanzu apps workload tail hello-servlet -n ${NAMESPACE}

すればテストが実行される。

$ kubectl get pipeline,pipelinerun -n ${NAMESPACE}
NAME                                                    AGE
pipeline.tekton.dev/developer-defined-tekton-pipeline   86m

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-b84fq   True        Succeeded   8m32s       6m43s

これだとnamespaceにつき1のパイプラインしか設定できない。つまりmaven testしか実行できない。

namespace内で複数のPipelineを使用できるようにするにはtemplateを直さないといけない。 https://docs.vmware.com/en/Tanzu-Application-Platform/1.1/tap//GUID-scc-ootb-supply-chain-testing.html#multiple-pl

いったんworkloadとpipelineは削除

tanzu apps workload delete hello-servlet -n ${NAMESPACE} -y
kubectl delete -f  pipeline.yaml -n ${NAMESPACE}
making commented 2 years ago

https://github.com/tanzu-japan/jaguchi-manifests/commit/f4f10ad50fe5dff1f206faece2d011ec7dc3fa6a のoverlayでselectormatchingLabelsapps.jaguchi.maki.lol/test-type: #@ data.values.workload.metadata.labels["apps.jaguchi.maki.lol/test-type"]を追加

$ kubectl get clustersourcetemplate testing-pipeline -oyaml | kubectl neat
apiVersion: carto.run/v1alpha1
kind: ClusterSourceTemplate
metadata:
  annotations:
    kapp.k14s.io/identity: v1;/carto.run/ClusterSourceTemplate/testing-pipeline;carto.run/v1alpha1
    kapp.k14s.io/original-diff-md5: c6e94dc94aed3401b5d0f26ed6c0bff3
  labels:
    kapp.k14s.io/app: "1652292541931031617"
    kapp.k14s.io/association: v1.50024c093435d6c798ab4a6429d20dc7
  name: testing-pipeline
spec:
  revisionPath: .status.outputs.revision
  urlPath: .status.outputs.url
  ytt: |
    #@ load("@ytt:data", "data")

    #@ def merge_labels(fixed_values):
    #@   labels = {}
    #@   if hasattr(data.values.workload.metadata, "labels"):
    #@     labels.update(data.values.workload.metadata.labels)
    #@   end
    #@   labels.update(fixed_values)
    #@   return labels
    #@ end

    apiVersion: carto.run/v1alpha1
    kind: Runnable
    metadata:
      name: #@ data.values.workload.metadata.name
      labels: #@ merge_labels({ "app.kubernetes.io/component": "test" })
    spec:
      #@ if/end hasattr(data.values.workload.spec, "serviceAccountName"):
      serviceAccountName: #@ data.values.workload.spec.serviceAccountName

      runTemplateRef:
        name: tekton-source-pipelinerun
        kind: ClusterRunTemplate

      selector:
        resource:
          apiVersion: tekton.dev/v1beta1
          kind: Pipeline
        matchingLabels:
          apps.tanzu.vmware.com/pipeline: test
          apps.jaguchi.maki.lol/test-type: #@ data.values.workload.metadata.labels["apps.jaguchi.maki.lol/test-type"]

      inputs:
        source-url: #@ data.values.source.url
        source-revision: #@ data.values.source.revision
making commented 2 years ago

Mavenのテスト

cat <<'EOF' > pipeline-maven.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: maven-test-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test
    apps.jaguchi.maki.lol/test-type: maven-jdk-17
spec:
  params:
  - name: source-url
  - name: source-revision
  tasks:
  - name: test
    params:
    - name: source-url
      value: $(params.source-url)
    - name: source-revision
      value: $(params.source-revision)
    taskSpec:
      params:
      - name: source-url
      - name: source-revision
      steps:
      - name: test
        image: eclipse-temurin:17
        script: |-
          set -ex
          cd `mktemp -d`
          curl -s $(params.source-url) | tar -xzvf -
          ./mvnw clean test -V --no-transfer-progress
EOF
kubectl apply -f pipeline-maven.yaml -n ${NAMESPACE}
tanzu apps workload apply hello-servlet \
  --app hello-servlet \
  --git-repo https://github.com/making/hello-servlet \
  --git-branch master \
  --type web \
  --label apps.tanzu.vmware.com/has-tests=true \
  --label apps.jaguchi.maki.lol/test-type=maven-jdk-17 \
  -n ${NAMESPACE} -y
tanzu apps workload tail hello-servlet -n ${NAMESPACE}
making commented 2 years ago

Gradleのテスト

cat <<'EOF' > pipeline-gradle.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: gradle-test-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test
    apps.jaguchi.maki.lol/test-type: gradle-jdk-17
spec:
  params:
  - name: source-url
  - name: source-revision
  tasks:
  - name: test
    params:
    - name: source-url
      value: $(params.source-url)
    - name: source-revision
      value: $(params.source-revision)
    taskSpec:
      params:
      - name: source-url
      - name: source-revision
      steps:
      - name: test
        image: eclipse-temurin:17
        script: |-
          set -ex
          cd `mktemp -d`
          curl -s $(params.source-url) | tar -xzvf -
          ./gradlew --no-daemon test
EOF
kubectl apply -f pipeline-gradle.yaml -n ${NAMESPACE}
tanzu apps workload apply spring-music \
  --app spring-music \
  --git-repo https://github.com/tanzu-japan/spring-music \
  --git-branch tanzu \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --label apps.tanzu.vmware.com/has-tests=true \
  --label apps.jaguchi.maki.lol/test-type=gradle-jdk-17 \
  -n ${NAMESPACE} -y
tanzu apps workload tail spring-music -n ${NAMESPACE}
making commented 2 years ago

Maven, Gradleそれぞれのテストを実行できている

$ kubectl get pipeline,pipelinerun -n ${NAMESPACE}
NAME                                       AGE
pipeline.tekton.dev/gradle-test-pipeline   11m
pipeline.tekton.dev/maven-test-pipeline    17m

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-tjvmq   True        Succeeded   17m         15m
pipelinerun.tekton.dev/spring-music-fk2g8    True        Succeeded   4m47s       39s
making commented 2 years ago

わざとテストを失敗してみる

commit前

$ kubectl get gitrepo,pipelinerun,build -n ${NAMESPACE} -l app.kubernetes.io/part-of=hello-servlet
NAME                                                   URL                                       READY   STATUS                                                              AGE
gitrepository.source.toolkit.fluxcd.io/hello-servlet   https://github.com/making/hello-servlet   True    Fetched revision: master/10c1f4fe94bf8e0609b977a9fb273dc6fd223a6e   7h42m

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-tjvmq   True        Succeeded   7h42m       7h40m

NAME                                   IMAGE                                                                                                          SUCCEEDED
build.kpack.io/hello-servlet-build-1   ghcr.io/jaguchi/hello-servlet-making@sha256:48fd6872e90f29ab13b5256bf6b778c9fd1a24eb9db47e1de9b78749a39d6c6e   True

commit https://github.com/making/hello-servlet/commit/b1b27376dcbc1f938b09c0210d0faff7f565316f

commit後

$ kubectl get gitrepo,pipelinerun,build -n ${NAMESPACE} -l app.kubernetes.io/part-of=hello-servlet 
NAME                                                   URL                                       READY   STATUS                                                              AGE
gitrepository.source.toolkit.fluxcd.io/hello-servlet   https://github.com/making/hello-servlet   True    Fetched revision: master/b1b27376dcbc1f938b09c0210d0faff7f565316f   7h47m

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-tjvmq   True        Succeeded   7h46m       7h45m
pipelinerun.tekton.dev/hello-servlet-v4gdk   False       Failed      2m16s       34s

NAME                                   IMAGE                                                                                                          SUCCEEDED
build.kpack.io/hello-servlet-build-1   ghcr.io/jaguchi/hello-servlet-making@sha256:48fd6872e90f29ab13b5256bf6b778c9fd1a24eb9db47e1de9b78749a39d6c6e   True

新しいbuildは産み出されない

making commented 2 years ago

テストを成功させる

commit https://github.com/making/hello-servlet/commit/52d3ce0ebf10deab0495845fd36027c5da39efc9

commit後

$ kubectl get gitrepo,pipelinerun,build -n ${NAMESPACE} -l app.kubernetes.io/part-of=hello-servlet 
NAME                                                   URL                                       READY   STATUS                                                              AGE
gitrepository.source.toolkit.fluxcd.io/hello-servlet   https://github.com/making/hello-servlet   True    Fetched revision: master/52d3ce0ebf10deab0495845fd36027c5da39efc9   7h58m

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-9zpzr   True        Succeeded   7m19s       5m38s
pipelinerun.tekton.dev/hello-servlet-tjvmq   True        Succeeded   7h58m       7h56m
pipelinerun.tekton.dev/hello-servlet-v4gdk   False       Failed      13m         11m

NAME                                   IMAGE                                                                                                          SUCCEEDED
build.kpack.io/hello-servlet-build-1   ghcr.io/jaguchi/hello-servlet-making@sha256:48fd6872e90f29ab13b5256bf6b778c9fd1a24eb9db47e1de9b78749a39d6c6e   True
build.kpack.io/hello-servlet-build-2   ghcr.io/jaguchi/hello-servlet-making@sha256:2f35667b9d941e63fdfaf774d5b48f774a9b817d65db7e75117e5f00fa2638e9   True

新しいbuildができる

$ curl https://hello-servlet-making.apps.jaguchi.maki.lol
Hello World!

デプロイされた