apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: publish-tekton-pipelines
spec:
  inputs:
    resources:
    - name: source
      type: git
      targetPath: go/src/github.com/tektoncd/pipeline
    - name: bucket
      type: storage
    params:
    - name: versionTag
      description: The vX.Y.Z version that the artifacts should be tagged with (including `v`)
    - name: imageRegistry
      description: TODO(#569) This is a hack to make it easy for folks to switch the registry being used by the many many image outputs
    - name: pathToProject
      description: The path to the folder in the go/src dir that contains the project, which is used by `ko` to name the resulting images
  outputs:
    resources:
    - name: bucket
      type: storage
    - name: builtBaseImage
      type: image
    - name: builtEntrypointImage
      type: image
    - name: builtKubeconfigWriterImage
      type: image
    - name: builtCredsInitImage
      type: image
    - name: builtGitInitImage
      type: image
    - name: builtControllerImage
      type: image
    - name: builtWebhookImage
      type: image
    - name: builtDigestExporterImage
      type: image
    - name: builtPullRequestInitImage
      type: image
    - name: builtGcsFetcherImage
      type: image
    - name: notification
      type: cloudEvent
  steps:

  - name: build-push-base-images
    image: gcr.io/kaniko-project/executor:v0.17.1
    command:
    - /kaniko/executor
    args:
    - --dockerfile=/workspace/go/src/github.com/tektoncd/pipeline/images/Dockerfile
    - --destination=$(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtBaseImage.url)
    - --context=/workspace/go/src/github.com/tektoncd/pipeline

    volumeMounts:
      - name: gcp-secret
        mountPath: /secret
    env:
      - name: GOOGLE_APPLICATION_CREDENTIALS
        value: /secret/release.json

  - name: create-ko-yaml
    image: busybox
    script: |
      #!/bin/sh
      set -ex

      cat <<EOF > /workspace/go/src/github.com/tektoncd/pipeline/.ko.yaml
      # By default ko will build images on top of distroless
      baseImageOverrides:
        $(inputs.params.pathToProject)/$(outputs.resources.builtCredsInitImage.url): $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/build-base:latest
        $(inputs.params.pathToProject)/$(outputs.resources.builtGitInitImage.url): $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/build-base:latest
        $(inputs.params.pathToProject)/$(outputs.resources.builtEntrypointImage.url): busybox # image should have shell in $PATH
      baseBuildOverrides:
        $(inputs.params.pathToProject)/$(outputs.resources.builtControllerImage.url):
          env:
            - name: CGO_ENABLED
              value: 1
          flags:
            - name: ldflags
              value: "-X $(inputs.params.pathToProject)/pkg/version.PipelineVersion=$(inputs.params.versionTag)"
      EOF

      cat /workspace/go/src/github.com/tektoncd/pipeline/.ko.yaml

  - name: link-input-bucket-to-output
    image: busybox
    command: ["cp"]
    args:
    - -r
    - "/workspace/bucket"
    - "/workspace/output/"

  - name: ensure-release-dirs-exist
    image: busybox
    command: ["mkdir"]
    args:
    - "-p"
    - "/workspace/output/bucket/latest/"
    - "/workspace/output/bucket/previous/"

  - name: run-ko
    # FIXME(vdemeester) use a tagged version once 0.2 is released
    image: gcr.io/tekton-releases/dogfooding/ko:gcloud-latest
    env:
    - name: KO_DOCKER_REPO
      value: $(inputs.params.imageRegistry)
    - name: GOPATH
      value: /workspace/go
    - name: GO111MODULE
      value: "off"
    - name: GOFLAGS
      value: "-mod=vendor"
    - name: CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
      value: /secret/release.json
    script: |
      #!/usr/bin/env bash
      set -ex

      # Auth with CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
      gcloud auth configure-docker

      # ko requires this variable to be set in order to set image creation timestamps correctly https://github.com/google/go-containerregistry/pull/146
      export SOURCE_DATE_EPOCH=`date +%s`

      # Change to directory with our .ko.yaml
      cd /workspace/go/src/github.com/tektoncd/pipeline

      # For each cmd/* directory, include a full gzipped tar of all source in
      # vendor/. This is overkill. Some deps' licenses require the source to be
      # included in the container image when they're used as a dependency.
      # Rather than trying to determine which deps have this requirement (and
      # probably get it wrong), we'll just targz up the whole vendor tree and
      # include it. As of 9/20/2019, this amounts to about 11MB of additional
      # data in each image.
      TMPDIR=$(mktemp -d)
      tar cvfz ${TMPDIR}/source.tar.gz vendor/
      for d in cmd/*; do
        ln -s ${TMPDIR}/source.tar.gz ${d}/kodata/
      done

      # Rewrite "devel" to inputs.params.versionTag
      sed -i 's/devel/$(inputs.params.versionTag)/g' /workspace/go/src/github.com/tektoncd/pipeline/config/controller.yaml
      sed -i 's/devel/$(inputs.params.versionTag)/g' /workspace/go/src/github.com/tektoncd/pipeline/config/webhook.yaml

      # Publish images and create release.yaml
      ko resolve --preserve-import-paths -t $(inputs.params.versionTag) -f /workspace/go/src/github.com/tektoncd/pipeline/config/ > /workspace/output/bucket/latest/release.yaml
      # Publish images and create release.notags.yaml
      # This is useful if your container runtime doesn't support the `image-reference:tag@digest` notation
      # This is currently the case for `cri-o` (and most likely others)
      ko resolve --preserve-import-paths -f /workspace/go/src/github.com/tektoncd/pipeline/config/ > /workspace/output/bucket/latest/release.notags.yaml
    volumeMounts:
      - name: gcp-secret
        mountPath: /secret

  - name: copy-to-tagged-bucket
    image: busybox
    workingDir: "/workspace/output/bucket"
    script: |
      #!/bin/sh
      set -ex

      mkdir -p /workspace/output/bucket/previous/$(inputs.params.versionTag)/
      cp /workspace/output/bucket/latest/release.yaml /workspace/output/bucket/previous/$(inputs.params.versionTag)/release.yaml
      cp /workspace/output/bucket/latest/release.notags.yaml /workspace/output/bucket/previous/$(inputs.params.versionTag)/release.notags.yaml

  - name: tag-images
    image: google/cloud-sdk
    script: |
      #!/usr/bin/env bash
      set -ex

      REGIONS=(us eu asia)
      IMAGES=(
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtEntrypointImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtKubeconfigWriterImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtCredsInitImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtGitInitImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtControllerImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtWebhookImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtDigestExporterImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtPullRequestInitImage.url):$(inputs.params.versionTag)
        $(inputs.params.imageRegistry)/$(inputs.params.pathToProject)/$(outputs.resources.builtGcsFetcherImage.url):$(inputs.params.versionTag)
      )
      # Parse the built images from the release.yaml generated by ko
      BUILT_IMAGES=( $(/workspace/go/src/github.com/tektoncd/pipeline/tekton/koparse/koparse.py --path /workspace/output/bucket/latest/release.yaml --base $(inputs.params.imageRegistry)/$(inputs.params.pathToProject) --images ${IMAGES[@]}) )

      # Auth with account credentials
      gcloud auth activate-service-account --key-file=/secret/release.json

      # Tag the images and put them in all the regions
      for IMAGE in "${BUILT_IMAGES[@]}"
      do
        IMAGE_WITHOUT_SHA=${IMAGE%%@*}
        IMAGE_WITHOUT_SHA_AND_TAG=${IMAGE_WITHOUT_SHA%%:*}
        IMAGE_WITH_SHA=${IMAGE_WITHOUT_SHA_AND_TAG}@${IMAGE##*@}
        gcloud -q container images add-tag ${IMAGE_WITH_SHA} ${IMAGE_WITHOUT_SHA_AND_TAG}:latest
        for REGION in "${REGIONS[@]}"
        do
          for TAG in "latest" $(inputs.params.versionTag)
          do
            gcloud -q container images add-tag ${IMAGE_WITH_SHA} ${REGION}.${IMAGE_WITHOUT_SHA_AND_TAG}:$TAG
          done
        done
      done
    volumeMounts:
      - name: gcp-secret
        mountPath: /secret

  volumes:
    - name: gcp-secret
      secret:
        secretName: release-secret
