216 lines
5.7 KiB
Bash
Executable File
216 lines
5.7 KiB
Bash
Executable File
#!/bin/bash -eu
|
|
|
|
# Publish any versions of the docker image not yet pushed to jenkins/jenkins
|
|
# Arguments:
|
|
# -n dry run, do not build or publish images
|
|
# -d debug
|
|
|
|
set -o pipefail
|
|
|
|
sort-versions() {
|
|
if [ "$(uname)" == 'Darwin' ]; then
|
|
gsort --version-sort
|
|
else
|
|
sort --version-sort
|
|
fi
|
|
}
|
|
|
|
# Try tagging with and without -f to support all versions of docker
|
|
docker-tag() {
|
|
local from="jenkins/jenkins:$1"
|
|
local to="$2/jenkins:$3"
|
|
local out
|
|
|
|
docker pull "$from"
|
|
if out=$(docker tag -f "$from" "$to" 2>&1); then
|
|
echo "$out"
|
|
else
|
|
docker tag "$from" "$to"
|
|
fi
|
|
}
|
|
|
|
login-token() {
|
|
# could use jq .token
|
|
curl -q -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:jenkins/jenkins:pull" | grep -o '"token":"[^"]*"' | cut -d':' -f 2 | xargs echo
|
|
}
|
|
|
|
is-published() {
|
|
local tag=$1
|
|
local opts=""
|
|
if [ "$debug" = true ]; then
|
|
opts="-v"
|
|
fi
|
|
local http_code;
|
|
http_code=$(curl $opts -q -fsL -o /dev/null -w "%{http_code}" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer $TOKEN" "https://index.docker.io/v2/jenkins/jenkins/manifests/$tag")
|
|
if [ "$http_code" -eq "404" ]; then
|
|
false
|
|
elif [ "$http_code" -eq "200" ]; then
|
|
true
|
|
else
|
|
echo "Received unexpected http code from Docker hub: $http_code"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
get-manifest() {
|
|
local tag=$1
|
|
local opts=""
|
|
if [ "$debug" = true ]; then
|
|
opts="-v"
|
|
fi
|
|
curl $opts -q -fsSL -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer $TOKEN" "https://index.docker.io/v2/jenkins/jenkins/manifests/$tag"
|
|
}
|
|
|
|
get-digest() {
|
|
local manifest
|
|
manifest=$(get-manifest "$1")
|
|
#get-manifest "$1" | jq .config.digest
|
|
if [ "$debug" = true ]; then
|
|
>&2 echo "DEBUG: Manifest for $1: $manifest"
|
|
fi
|
|
echo "$manifest" | grep -A 10 -o '"config".*' | grep digest | head -1 | cut -d':' -f 2,3 | xargs echo
|
|
}
|
|
|
|
get-latest-versions() {
|
|
curl -q -fsSL https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/maven-metadata.xml | grep '<version>.*</version>' | grep -E -o '[0-9]+(\.[0-9]+)+' | sort-versions | uniq | tail -n 20
|
|
}
|
|
|
|
publish() {
|
|
local version=$1
|
|
local variant=$2
|
|
local tag="${version}${variant}"
|
|
local sha
|
|
local build_opts=(--no-cache --pull)
|
|
|
|
if [ "$dry_run" = true ]; then
|
|
build_opts=()
|
|
fi
|
|
|
|
sha=$(curl -q -fsSL "https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/${version}/jenkins-war-${version}.war.sha256" )
|
|
|
|
docker build --file "Dockerfile$variant" \
|
|
--build-arg "JENKINS_VERSION=$version" \
|
|
--build-arg "JENKINS_SHA=$sha" \
|
|
--tag "jenkins/jenkins:${tag}" \
|
|
--tag "jenkinsci/jenkins:${tag}" \
|
|
"${build_opts[@]+"${build_opts[@]}"}" .
|
|
|
|
# " line to fix syntax highlightning
|
|
if [ ! "$dry_run" = true ]; then
|
|
docker push "jenkins/jenkins:${tag}"
|
|
docker push "jenkinsci/jenkins:${tag}"
|
|
fi
|
|
}
|
|
|
|
tag-and-push() {
|
|
local source=$1
|
|
local target=$2
|
|
local digest_source
|
|
local digest_target
|
|
|
|
if [ "$debug" = true ]; then
|
|
>&2 echo "DEBUG: Getting digest for ${source}"
|
|
fi
|
|
# if tag doesn't exist yet, ie. dry run
|
|
if ! digest_source=$(get-digest "${source}"); then
|
|
echo "Unable to get digest for ${source} ${digest_source}"
|
|
digest_source=""
|
|
fi
|
|
|
|
if [ "$debug" = true ]; then
|
|
>&2 echo "DEBUG: Getting digest for ${target}"
|
|
fi
|
|
if ! digest_target=$(get-digest "${target}"); then
|
|
echo "Unable to get digest for ${target} ${digest_target}"
|
|
digest_target=""
|
|
fi
|
|
|
|
if [ "$digest_source" == "$digest_target" ] && [ -n "${digest_target}" ]; then
|
|
echo "Images ${source} [$digest_source] and ${target} [$digest_target] are already the same, not updating tags"
|
|
else
|
|
echo "Creating tag ${target} pointing to ${source}"
|
|
docker-tag "${source}" "jenkins" "${target}"
|
|
docker-tag "${source}" "jenkinsci" "${target}"
|
|
if [ ! "$dry_run" = true ]; then
|
|
echo "Pushing jenkins/jenkins:${target}"
|
|
docker push "jenkins/jenkins:${target}"
|
|
docker push "jenkinsci/jenkins:${target}"
|
|
else
|
|
echo "Would push jenkins/jenkins:${target}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
publish-latest() {
|
|
local version=$1
|
|
local variant=$2
|
|
|
|
# push latest (for master) or the name of the branch (for other branches)
|
|
if [ -z "${variant}" ]; then
|
|
tag-and-push "${version}${variant}" "latest"
|
|
else
|
|
tag-and-push "${version}${variant}" "${variant#-}"
|
|
fi
|
|
}
|
|
|
|
publish-lts() {
|
|
local version=$1
|
|
local variant=$2
|
|
tag-and-push "${version}${variant}" "lts${variant}"
|
|
}
|
|
|
|
# Process arguments
|
|
|
|
dry_run=false
|
|
debug=false
|
|
variant=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
key="$1"
|
|
case $key in
|
|
-n)
|
|
dry_run=true
|
|
;;
|
|
-d)
|
|
debug=true
|
|
;;
|
|
-v|--variant)
|
|
variant="-"$2
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Unknown option: $key"
|
|
return 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
|
|
if [ "$dry_run" = true ]; then
|
|
echo "Dry run, will not publish images"
|
|
fi
|
|
|
|
TOKEN=$(login-token)
|
|
|
|
lts_version=""
|
|
version=""
|
|
for version in $(get-latest-versions); do
|
|
if is-published "$version$variant"; then
|
|
echo "Tag is already published: $version$variant"
|
|
else
|
|
echo "Publishing version: $version$variant"
|
|
publish "$version" "$variant"
|
|
fi
|
|
|
|
# Update lts tag
|
|
if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
lts_version="${version}"
|
|
fi
|
|
done
|
|
|
|
publish-latest "${version}" "${variant}"
|
|
if [ -n "${lts_version}" ]; then
|
|
publish-lts "${lts_version}" "${variant}"
|
|
fi
|