blob: 8c14dddf30307961f20ea7685b2eca1843e047e8 [file] [log] [blame]
Zack Williams12783ac2018-06-12 15:13:12 -07001#!/usr/bin/env bash
2
3# Copyright 2018-present Open Networking Foundation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# versiontag.sh
18# Tags a git commit with the SemVer version discovered within the commit,
19# if the tag doesn't already exist. Ignore non-SemVer commits.
20
21set -eu -o pipefail
22
Zack Williams8e69efd2018-06-13 15:05:18 -070023VERSIONFILE="" # file path to file containing version number
24NEW_VERSION="" # version number found in $VERSIONFILE
Zack Williams6e070f52019-10-04 11:08:59 -070025TAG_VERSION="" # version file that might have a leading v to work around go mod funkyness
Zack Williams12783ac2018-06-12 15:13:12 -070026
Zack Williams66500002018-09-06 15:29:05 -070027SEMVER_STRICT=${SEMVER_STRICT:-0} # require semver versions
28
Zack Williams12783ac2018-06-12 15:13:12 -070029releaseversion=0
Zack Williams8e69efd2018-06-13 15:05:18 -070030fail_validation=0
31
32# when not running under Jenkins, use current dir as workspace
33WORKSPACE=${WORKSPACE:-.}
Zack Williams12783ac2018-06-12 15:13:12 -070034
35# find the version string in the repo, read into NEW_VERSION
36# Add additional places NEW_VERSION could be found to this function
37function read_version {
38 if [ -f "VERSION" ]
39 then
40 NEW_VERSION=$(head -n1 "VERSION")
41 VERSIONFILE="VERSION"
Zack Williams6e070f52019-10-04 11:08:59 -070042
43 # If this is a golang project, use funky v-prefixed versions
44 if [ -f "Gopkg.toml" ] || [ -f "go.mod" ]
45 then
46 echo "go-based project found, using v-prefixed version for git tags: v${NEW_VERSION}"
47 TAG_VERSION=v${NEW_VERSION}
48 else
49 TAG_VERSION=${NEW_VERSION}
50 fi
51
Zack Williams6a9d2e62018-06-22 15:18:23 -070052 elif [ -f "package.json" ]
53 then
54 NEW_VERSION=$(python -c 'import json,sys;obj=json.load(sys.stdin); print obj["version"]' < package.json)
Zack Williams6e070f52019-10-04 11:08:59 -070055 TAG_VERSION=$NEW_VERSION
Zack Williams6a9d2e62018-06-22 15:18:23 -070056 VERSIONFILE="package.json"
Zack Williams866ef3c2019-09-27 15:41:02 -070057 elif [ -f "pom.xml" ]
58 then
59 NEW_VERSION=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml)
Zack Williams6e070f52019-10-04 11:08:59 -070060 TAG_VERSION=$NEW_VERSION
Zack Williams866ef3c2019-09-27 15:41:02 -070061 VERSIONFILE="pom.xml"
Zack Williams12783ac2018-06-12 15:13:12 -070062 else
63 echo "ERROR: No versioning file found!"
64 exit 1
65 fi
66}
67
Zack Williams8e69efd2018-06-13 15:05:18 -070068# check if the version is a released version
69function check_if_releaseversion {
70 if [[ "$NEW_VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
71 then
72 echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is a SemVer released version!"
73 releaseversion=1
74 else
Zack Williams66500002018-09-06 15:29:05 -070075 if [ "$SEMVER_STRICT" -eq "1" ]
76 then
77 echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, SEMVER_STRICT enabled, failing!"
78 fail_validation=1
79 else
80 echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, skipping."
81 fi
Zack Williams8e69efd2018-06-13 15:05:18 -070082 fi
83}
84
Zack Williams12783ac2018-06-12 15:13:12 -070085# check if the version is already a tag in git
86function is_git_tag_duplicated {
87 for existing_tag in $(git tag)
88 do
Zack Williams6e070f52019-10-04 11:08:59 -070089 if [ "$TAG_VERSION" = "$existing_tag" ]
Zack Williams12783ac2018-06-12 15:13:12 -070090 then
91 echo "ERROR: Duplicate tag: $existing_tag"
92 exit 2
93 fi
94 done
95}
96
Zack Williams8e69efd2018-06-13 15:05:18 -070097# check if Dockerfiles have a released version as their parent
98function dockerfile_parentcheck {
99 while IFS= read -r -d '' dockerfile
100 do
101 echo "Checking dockerfile: '$dockerfile'"
102
103 # split on newlines
104 IFS=$'\n'
105 df_parents=($(grep "^FROM" "$dockerfile"))
106
107 # check all parents in the Dockerfile
108 for df_parent in "${df_parents[@]}"
109 do
110
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000111 df_pattern="[FfRrOoMm] +(--platform=[^ ]+ +)?([^@: ]+)(:([^: ]+)|@sha[^ ]+)?"
Zack Williams8e69efd2018-06-13 15:05:18 -0700112 if [[ "$df_parent" =~ $df_pattern ]]
113 then
114
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000115 p_image="${BASH_REMATCH[2]}"
116 p_sha=${BASH_REMATCH[3]}
117 p_version="${BASH_REMATCH[4]}"
Zack Williams8e69efd2018-06-13 15:05:18 -0700118
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000119 echo "IMAGE: '${p_image}'"
120 echo "VERSION: '$p_version'"
121 echo "SHA: '$p_sha'"
122
123 if [[ "${p_image}" == "scratch" ]]
124 then
125 echo " OK: Using the versionless 'scratch' parent: '$df_parent'"
126 elif [[ "${p_image}:${p_version}" == "gcr.io/distroless/static:nonroot" ]]
127 then
128 echo " OK: Using static distroless image with nonroot: '${p_image}:${p_version}'"
129 elif [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
Zack Williams8e69efd2018-06-13 15:05:18 -0700130 then
131 echo " OK: Parent '$p_image:$p_version' is a released SemVer version"
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000132 elif [[ "${p_sha}" =~ ^@sha256:[0-9a-f]{64}.*$ ]]
Zack Williamsc800dbe2020-02-14 10:25:12 -0700133 then
134 # allow sha256 hashes to be used as version specifiers
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000135 echo " OK: Parent '$p_image$p_sha' is using a specific sha256 hash as a version"
Zack Williams0dc27542018-10-11 08:09:10 -0700136 elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
Zack Williams8e69efd2018-06-13 15:05:18 -0700137 then
Zack Williams0dc27542018-10-11 08:09:10 -0700138 # handle non-SemVer versions that have a Major.Minor version specifier in the name
139 # 'ubuntu:16.04'
140 # 'postgres:10.3-alpine'
141 # 'openjdk:8-jre-alpine3.8'
Zack Williams8e69efd2018-06-13 15:05:18 -0700142 echo " OK: Parent '$p_image:$p_version' is using a non-SemVer, but sufficient, version"
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000143 elif [[ -z "${p_version}" ]]
144 then
145 echo " ERROR: Parent '$p_image' is NOT using a specific version"
146 fail_validation=1
Zack Williams8e69efd2018-06-13 15:05:18 -0700147 else
David K. Bainbridgecc8127b2021-04-07 15:51:30 +0000148 echo " ERROR: Parent '$p_image:$p_version' is NOT using a specific version"
Zack Williams8e69efd2018-06-13 15:05:18 -0700149 fail_validation=1
150 fi
151
Zack Williams8e69efd2018-06-13 15:05:18 -0700152 else
153 echo " ERROR: Couldn't find a parent image in $df_parent"
154 fi
155
156 done
157
Matteo Scandolob28a02e2019-11-04 09:35:16 -0800158 done < <( find "${WORKSPACE}" -name 'Dockerfile*' ! -path "*/vendor/*" ! -name "*dockerignore" -print0 )
Zack Williams12783ac2018-06-12 15:13:12 -0700159}
160
Zack Williams8e69efd2018-06-13 15:05:18 -0700161
Zack Williams12783ac2018-06-12 15:13:12 -0700162# create a git tag
163function create_git_tag {
Zack Williams6e070f52019-10-04 11:08:59 -0700164 echo "Creating git tag: $TAG_VERSION"
Zack Williams12783ac2018-06-12 15:13:12 -0700165 git checkout "$GERRIT_PATCHSET_REVISION"
Zack Williams8e69efd2018-06-13 15:05:18 -0700166
Zack Williams7a7a3182020-08-13 14:15:40 -0700167 git config --global user.email "do-not-reply@opennetworking.org"
Zack Williams8e69efd2018-06-13 15:05:18 -0700168 git config --global user.name "Jenkins"
169
Zack Williams6e070f52019-10-04 11:08:59 -0700170 git tag -a "$TAG_VERSION" -m "Tagged by CORD Jenkins version-tag job: $BUILD_NUMBER, for Gerrit patchset: $GERRIT_CHANGE_NUMBER"
Zack Williams8e69efd2018-06-13 15:05:18 -0700171
172 echo "Tags including new tag:"
173 git tag -n
174
Zack Williams6e070f52019-10-04 11:08:59 -0700175 git push origin "$TAG_VERSION"
Zack Williams12783ac2018-06-12 15:13:12 -0700176}
177
178echo "Checking git repo with remotes:"
179git remote -v
180
181echo "Branches:"
182git branch -v
183
184echo "Existing git tags:"
185git tag -n
186
187read_version
Zack Williams8e69efd2018-06-13 15:05:18 -0700188check_if_releaseversion
Zack Williams12783ac2018-06-12 15:13:12 -0700189
Zack Williams8e69efd2018-06-13 15:05:18 -0700190# perform checks if a released version
191if [ "$releaseversion" -eq "1" ]
Zack Williams12783ac2018-06-12 15:13:12 -0700192then
Zack Williams8e69efd2018-06-13 15:05:18 -0700193 is_git_tag_duplicated
194 dockerfile_parentcheck
195
196 if [ "$fail_validation" -eq "0" ]
197 then
198 create_git_tag
199 else
200 echo "ERROR: commit merged but failed validation, not tagging!"
201 fi
Zack Williams12783ac2018-06-12 15:13:12 -0700202fi
203
Zack Williams8e69efd2018-06-13 15:05:18 -0700204exit $fail_validation