-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
publish.yaml
275 lines (246 loc) · 11.4 KB
/
publish.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: publish-release
annotations:
chains.tekton.dev/transparency-upload: "true"
spec:
params:
- name: package
description: package to release (e.g. github.com/<org>/<project>)
default: github.com/tektoncd/pipeline
- name: images
description: List of cmd/* paths to be published as images
default: "controller webhook entrypoint nop workingdirinit resolvers sidecarlogresults events"
- name: koExtraArgs
description: Extra args to be passed to ko
default: "--preserve-import-paths"
- name: versionTag
description: The vX.Y.Z version that the artifacts should be tagged with (including `v`)
- name: imageRegistry
description: The target image registry
default: gcr.io
- name: imageRegistryPath
description: The path (project) in the image registry
- name: imageRegistryRegions
description: The target image registry regions
default: "us eu asia"
- name: imageRegistryUser
description: Username to be used to login to the container registry
default: "_json_key"
- name: releaseAsLatest
description: Whether to tag and publish this release as Pipelines' latest
default: "true"
- name: platforms
description: Platforms to publish for the images (e.g. linux/amd64,linux/arm64)
default: linux/amd64,linux/arm,linux/arm64,linux/s390x,linux/ppc64le,windows/amd64
- name: serviceAccountPath
description: The name of the service account path within the release-secret workspace
workspaces:
- name: source
description: >-
The workspace where the repo has been cloned. This should ideally
be /go/src/$(params.package) however that is not possible today,
see https://github.com/tektoncd/pipeline/issues/3786. To use this
task on a fork of pipeline change the mountPath below
mountPath: /go/src/github.com/tektoncd/pipeline
- name: release-secret
description: The secret that contains a service account authorized to push to the imageRegistry and to the output bucket
- name: output
description: The release YAML will be written to this workspace
stepTemplate:
env:
- name: "PROJECT_ROOT"
value: "$(workspaces.source.path)"
- name: CONTAINER_REGISTRY_CREDENTIALS
value: "$(workspaces.release-secret.path)/$(params.serviceAccountPath)"
- name: CONTAINER_REGISTRY
value: "$(params.imageRegistry)/$(params.imageRegistryPath)"
- name: IMAGE_REGISTRY_PATH
value: "$(params.imageRegistryPath)"
- name: CONTAINER_REGISTRY_USER
value: "$(params.imageRegistryUser)"
- name: REGIONS
value: "$(params.imageRegistryRegions)"
- name: OUTPUT_RELEASE_DIR
value: "$(workspaces.output.path)/$(params.versionTag)"
- name: KO_EXTRA_ARGS
value: "$(params.koExtraArgs)"
results:
# IMAGES result is picked up by Tekton Chains to sign the release.
# See https://github.com/tektoncd/plumbing/blob/main/docs/signing.md for more info.
- name: IMAGES
steps:
- name: container-registry-auth
image: cgr.dev/chainguard/crane:latest-dev@sha256:b34abb5bf41822ed24ce4f25524f91a8df24d5355301b87ea4922ba060c2832d
script: |
#!/bin/sh
set -ex
# Login to the container registry
DOCKER_CONFIG=$(cat ${CONTAINER_REGISTRY_CREDENTIALS} | \
crane auth login -u ${CONTAINER_REGISTRY_USER} --password-stdin $(params.imageRegistry) 2>&1 | \
sed 's,^.*logged in via \(.*\)$,\1,g')
# Auth with account credentials for all regions.
for region in ${REGIONS}
do
HOSTNAME=${region}.$(params.imageRegistry)
cat ${CONTAINER_REGISTRY_CREDENTIALS} | crane auth login -u ${CONTAINER_REGISTRY_USER} --password-stdin ${HOSTNAME}
done
cp ${DOCKER_CONFIG} /workspace/docker-config.json
- name: create-ko-yaml
image: cgr.dev/chainguard/go:latest-dev@sha256:3e7edcd0d21e727d21946f4f500aaf1f4432dd60244079ac2c9426dbbe7bc115
script: |
#!/bin/sh
set -ex
# Setup docker-auth
DOCKER_CONFIG=~/.docker
mkdir -p ${DOCKER_CONFIG}
cp /workspace/docker-config.json ${DOCKER_CONFIG}/config.json
# Change to directory with vendor/
cd ${PROJECT_ROOT}
COMBINED_BASE_IMAGE_BASE=${CONTAINER_REGISTRY}
# If the IMAGE_REGISTRY_PATH does not already includes the package, add it
# Package looks like github.com/<org>/<repo>
# Path may look like "tekton-releases" or "tektoncd/pipeline"
if [[ ! "$(params.package)" == "github.com/${IMAGE_REGISTRY_PATH}" ]]; then
COMBINED_BASE_IMAGE_BASE=${COMBINED_BASE_IMAGE_BASE}/${IMAGE_REGISTRY_PATH}
fi
# Combine Distroless with a Windows base image, used for the entrypoint image.
# Distroless is pinned to the last version based on Alpine 3.18. Newer versions are based on Alpine 3.19_alpha20230901.
COMBINED_BASE_IMAGE=$(go run ./vendor/github.com/tektoncd/plumbing/cmd/combine/main.go \
cgr.dev/chainguard/static@sha256:67a1b00e0134e2b3a614c7198a26f7deed9d11b7acad4d52c79c0cfd47a2eae7 \
mcr.microsoft.com/windows/nanoserver:ltsc2019 \
mcr.microsoft.com/windows/nanoserver:ltsc2022 \
${COMBINED_BASE_IMAGE_BASE}/combined-base-image:latest)
# NOTE: Make sure this list of images to use the combined base image is in sync with what's in test/presubmit-tests.sh's 'ko_resolve' function.
cat <<EOF > /workspace/.ko.yaml
# This matches the value configured in .ko.yaml
defaultBaseImage: cgr.dev/chainguard/static@sha256:67a1b00e0134e2b3a614c7198a26f7deed9d11b7acad4d52c79c0cfd47a2eae7
baseImageOverrides:
# Use the combined base image for images that should include Windows support.
$(params.package)/cmd/entrypoint: ${COMBINED_BASE_IMAGE}
$(params.package)/cmd/nop: ${COMBINED_BASE_IMAGE}
$(params.package)/cmd/workingdirinit: ${COMBINED_BASE_IMAGE}
EOF
cat /workspace/.ko.yaml
- name: run-ko
image: gcr.io/tekton-releases/dogfooding/ko@sha256:a91cdc055ee8727860d35b1aa31940b3552395e5f5d273b698ef6fcb0fa786c1
env:
- name: KO_DOCKER_REPO
value: $(params.imageRegistry)/$(params.imageRegistryPath)
- name: GOFLAGS
value: "-mod=vendor"
script: |
#!/usr/bin/env sh
set -ex
# Use the generated `.ko.yaml`
export KO_CONFIG_PATH=/workspace
cat ${KO_CONFIG_PATH}/.ko.yaml
# Setup docker-auth
DOCKER_CONFIG=~/.docker
mkdir -p ${DOCKER_CONFIG}
cp /workspace/docker-config.json ${DOCKER_CONFIG}/config.json
# Change to directory with our .ko.yaml
cd ${PROJECT_ROOT}
# 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 cfz ${TMPDIR}/source.tar.gz vendor/
for d in cmd/*; do
if [ -d ${d}/kodata/ ]; then
ln -s ${TMPDIR}/source.tar.gz ${d}/kodata/
fi
done
# Publish images and create release.yaml
mkdir -p $OUTPUT_RELEASE_DIR
# Make a local git tag to make git status happy :)
# The real "tagging" will happen with the "create-release" pipeline.
git tag $(params.versionTag)
ko resolve \
--image-label=org.opencontainers.image.source=https://$(params.package) \
--platform=$(params.platforms) \
-t $(params.versionTag) \
-R ${KO_EXTRA_ARGS} \
-f ${PROJECT_ROOT}/config/ > $OUTPUT_RELEASE_DIR/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 \
--image-label=org.opencontainers.image.source=https://$(params.package) \
--platform=$(params.platforms) \
-R ${KO_EXTRA_ARGS} \
-f ${PROJECT_ROOT}/config/ > $OUTPUT_RELEASE_DIR/release.notags.yaml
# Rewrite "devel" to params.versionTag
sed -i -e 's/\(pipeline.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' ${OUTPUT_RELEASE_DIR}/release.yaml
sed -i -e 's/\(pipeline.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' ${OUTPUT_RELEASE_DIR}/release.notags.yaml
- name: koparse
image: gcr.io/tekton-releases/dogfooding/koparse@sha256:194c2ab9dce5f778ed757af13c626d6b85f15452e2c2902c79b0d0f5a0adf4d1
script: |
set -ex
# Find "--preserve-import-paths" in a list of args
function find_preserve_import_path() {
for arg in $@; do
if [[ "$arg" == "--preserve-import-paths" ]]; then
return 0
fi
done
return 1
}
# If "--preserve-import-paths" is used, include "package" in the expected path
find_preserve_import_path \
$(echo $KO_EXTRA_ARGS) && \
PRESERVE_IMPORT_PATH="--preserve-path" || \
PRESERVE_IMPORT_PATH="--no-preserve-path"
for cmd in $(params.images)
do
IMAGES="${IMAGES} $(params.package)/cmd/${cmd}:$(params.versionTag)"
done
# Parse the built images from the release.yaml generated by ko
koparse \
--path $OUTPUT_RELEASE_DIR/release.yaml \
--base $(params.package) \
--container-registry ${CONTAINER_REGISTRY} \
--images ${IMAGES} \
${PRESERVE_IMPORT_PATH} > /workspace/built_images
- name: tag-images
image: cgr.dev/chainguard/crane:latest-dev@sha256:b34abb5bf41822ed24ce4f25524f91a8df24d5355301b87ea4922ba060c2832d
script: |
#!/bin/sh
set -ex
# Setup docker-auth
DOCKER_CONFIG=~/.docker
mkdir -p ${DOCKER_CONFIG}
cp /workspace/docker-config.json ${DOCKER_CONFIG}/config.json
# Tag the images and put them in all the regions
for IMAGE in $(cat /workspace/built_images)
do
IMAGE_WITHOUT_SHA=${IMAGE%%@*}
IMAGE_WITHOUT_SHA_AND_TAG=${IMAGE_WITHOUT_SHA%%:*}
IMAGE_WITH_SHA=${IMAGE_WITHOUT_SHA_AND_TAG}@${IMAGE##*@}
echo $IMAGE_WITH_SHA, >> $(results.IMAGES.path)
if [[ "$(params.releaseAsLatest)" == "true" ]]
then
crane cp ${IMAGE_WITH_SHA} ${IMAGE_WITHOUT_SHA_AND_TAG}:latest
fi
for REGION in ${REGIONS}
do
if [[ "$(params.releaseAsLatest)" == "true" ]]
then
for TAG in "latest" $(params.versionTag)
do
crane cp ${IMAGE_WITH_SHA} ${REGION}.${IMAGE_WITHOUT_SHA_AND_TAG}:$TAG
done
else
TAG="$(params.versionTag)"
crane cp ${IMAGE_WITH_SHA} ${REGION}.${IMAGE_WITHOUT_SHA_AND_TAG}:$TAG
fi
# Until we are able to store larger results, we cannot include the
# regional copies of the images in the result - see https://github.com/tektoncd/pipeline/issues/4282
# echo ${REGION}.$IMAGE_WITH_SHA, >> $(results.IMAGES.path)
done
done