Skip to content

Commit 20cfb7e

Browse files
hessjcgkgala2
andauthored
chore: Add build script to run cross-project common build commands. (#697)
This creates a standardized developer commands script "build.sh" that will exist in this and all other Cloud SQL Connector projects. See also: GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#2122 Co-authored-by: kgala2 <[email protected]>
1 parent d8bacd5 commit 20cfb7e

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

build.sh

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2025 Google LLC.
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+
# Set SCRIPT_DIR to the current directory of this file.
18+
SCRIPT_DIR=$(cd -P "$(dirname "$0")" >/dev/null 2>&1 && pwd)
19+
SCRIPT_FILE="${SCRIPT_DIR}/$(basename "$0")"
20+
21+
##
22+
## Local Development
23+
##
24+
## These functions should be used to run the local development process
25+
##
26+
27+
## clean - Cleans the build output
28+
function clean() {
29+
make clean
30+
}
31+
32+
## build - Builds the project without running tests.
33+
function build() {
34+
make build
35+
}
36+
37+
## test - Runs local unit tests.
38+
function test() {
39+
make test
40+
}
41+
42+
## e2e - Runs end-to-end integration tests.
43+
function e2e() {
44+
if [[ ! -f .envrc ]] ; then
45+
write_e2e_env .envrc
46+
fi
47+
source .envrc
48+
make e2e_test
49+
}
50+
51+
function get_golang_tool() {
52+
name="$1"
53+
github_repo="$2"
54+
package="$3"
55+
56+
# Download goimports tool
57+
version=$(curl -s "https://api.github.com/repos/$github_repo/tags" | jq -r '.[].name' | head -n 1)
58+
mkdir -p "$SCRIPT_DIR/.tools"
59+
cmd="$SCRIPT_DIR/.tools/$name"
60+
versioned_cmd="$SCRIPT_DIR/.tools/$name-$version"
61+
if [[ ! -f "$versioned_cmd" ]] ; then
62+
GOBIN="$SCRIPT_DIR/.tools" go install "$package@$version"
63+
mv "$cmd" "$versioned_cmd"
64+
if [[ -f "$cmd" ]] ; then
65+
unlink "$cmd"
66+
fi
67+
ln -s "$versioned_cmd" "$cmd"
68+
fi
69+
}
70+
71+
## fix - Fixes code format.
72+
function fix() {
73+
# run code formatting
74+
get_golang_tool 'goimports' 'golang/tools' 'golang.org/x/tools/cmd/goimports'
75+
".tools/goimports" -w .
76+
go mod tidy
77+
go fmt ./...
78+
}
79+
80+
## lint - runs the linters
81+
function lint() {
82+
# run lint checks
83+
get_golang_tool 'golangci-lint' 'golangci/golangci-lint' 'github.com/golangci/golangci-lint/v2/cmd/golangci-lint'
84+
".tools/golangci-lint" run --timeout 3m
85+
86+
# Check the commit includes a go.mod that is fully
87+
# up to date.
88+
fix
89+
if [[ -d "$SCRIPT_DIR/.git" ]] ; then
90+
git diff --exit-code
91+
fi
92+
}
93+
94+
## deps - updates project dependencies to latest
95+
function deps() {
96+
# Remove all indirect deps
97+
grep -v '// indirect' go.mod > go.mod.tmp
98+
rm go.mod
99+
mv go.mod.tmp go.mod
100+
101+
# Update deps
102+
go get -t -u ./...
103+
go mod tidy
104+
105+
# Update the image label in the dockerfiles
106+
for n in Dockerfile Dockerfile-operator ; do
107+
dockerfile_from_deps "$n"
108+
done
109+
}
110+
111+
# find
112+
function dockerfile_from_deps() {
113+
# FROM gcr.io/distroless/static:nonroot@sha256:627d6c5a23ad24e6bdff827f16c7b60e0289029b0c79e9f7ccd54ae3279fb45f
114+
# curl -X GET https://gcr.io/v2/distroless/static/manifests/nonroot
115+
file=$1
116+
117+
# Get the last FROM statement from the dockerfile
118+
# those ar
119+
fromLine=$(grep "FROM" $1 | tail -n1)
120+
imageUrl="${fromLine#FROM *}"
121+
122+
# If the image URL does not contain a hash, then don't do anything.
123+
if [[ $imageUrl != *@* ]] ; then
124+
echo "Image does not contain a digest, ignoring"
125+
return
126+
fi
127+
128+
oldDigest="${imageUrl#*@}" #after the '@'
129+
imageWithoutHash="${imageUrl%%@sha256*}" #before the '@sha256'
130+
imageName="${imageWithoutHash%%:*}" #before the ':'
131+
132+
imageLabel="${imageWithoutHash#*:}" #after the ':'
133+
# If none found, use "latest" as the label
134+
if [[ "$imageLabel" == "$imageName" ]] ; then
135+
imageLabel=latest
136+
fi
137+
138+
imageRepo="${imageName%%/*}" #first part of the image name path, may be a repo hostname
139+
if [[ "$imageRepo" == *.* ]]; then
140+
imageName="${imageName#*/}" # trim repo name host from imageName
141+
manifestUrl="https://${imageRepo}/v2/${imageName}/manifests/${imageLabel}"
142+
digest=$(curl -X GET "$manifestUrl" | \
143+
jq -r '.manifests[] | select(.platform.architecture=="amd64" and .platform.os=="linux") | .digest')
144+
145+
else
146+
# registry-1.docker.io requires a token
147+
docker_io_token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull" | jq -r .token)
148+
manifestUrl="https://registry-1.docker.io/v2/${imageName}/manifests/${imageLabel}"
149+
digest=$(curl -s -H "Authorization: Bearer $docker_io_token" \
150+
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
151+
https://registry-1.docker.io/v2/library/alpine/manifests/3 | \
152+
jq -r '.manifests[] | select(.platform.architecture=="amd64" and .platform.os=="linux") | .digest')
153+
fi
154+
155+
if [[ "$oldDigest" == "$digest" ]] ; then
156+
echo "No update to image to $file"
157+
else
158+
echo "Updating docker image to $file to $digest"
159+
set -x
160+
sed -i "" "s/$oldDigest/$digest/g" "$file"
161+
fi
162+
163+
}
164+
165+
# write_e2e_env - Loads secrets from the gcloud project and writes
166+
# them to target/e2e.env to run e2e tests.
167+
function write_e2e_env(){
168+
# All secrets used by the e2e tests in the form <env_name>=<secret_name>
169+
secret_vars=(
170+
MYSQL_CONNECTION_NAME=MYSQL_CONNECTION_NAME
171+
MYSQL_USER=MYSQL_USER
172+
MYSQL_PASS=MYSQL_PASS
173+
MYSQL_DB=MYSQL_DB
174+
MYSQL_MCP_CONNECTION_NAME=MYSQL_MCP_CONNECTION_NAME
175+
MYSQL_MCP_PASS=MYSQL_MCP_PASS
176+
POSTGRES_CONNECTION_NAME=POSTGRES_CONNECTION_NAME
177+
POSTGRES_USER=POSTGRES_USER
178+
POSTGRES_USER_IAM=POSTGRES_USER_IAM
179+
POSTGRES_PASS=POSTGRES_PASS
180+
POSTGRES_DB=POSTGRES_DB
181+
POSTGRES_CAS_CONNECTION_NAME=POSTGRES_CAS_CONNECTION_NAME
182+
POSTGRES_CAS_PASS=POSTGRES_CAS_PASS
183+
POSTGRES_CUSTOMER_CAS_CONNECTION_NAME=POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
184+
POSTGRES_CUSTOMER_CAS_PASS=POSTGRES_CUSTOMER_CAS_PASS
185+
POSTGRES_CUSTOMER_CAS_DOMAIN_NAME=POSTGRES_CUSTOMER_CAS_DOMAIN_NAME
186+
POSTGRES_MCP_CONNECTION_NAME=POSTGRES_MCP_CONNECTION_NAME
187+
POSTGRES_MCP_PASS=POSTGRES_MCP_PASS
188+
SQLSERVER_CONNECTION_NAME=SQLSERVER_CONNECTION_NAME
189+
SQLSERVER_USER=SQLSERVER_USER
190+
SQLSERVER_PASS=SQLSERVER_PASS
191+
SQLSERVER_DB=SQLSERVER_DB
192+
IMPERSONATED_USER=IMPERSONATED_USER
193+
)
194+
195+
if [[ -z "$TEST_PROJECT" ]] ; then
196+
echo "Set TEST_PROJECT environment variable to the project containing"
197+
echo "the e2e test suite secrets."
198+
exit 1
199+
fi
200+
201+
echo "Getting test secrets from $TEST_PROJECT into $1"
202+
{
203+
for env_name in "${secret_vars[@]}" ; do
204+
env_var_name="${env_name%%=*}"
205+
secret_name="${env_name##*=}"
206+
set -x
207+
val=$(gcloud secrets versions access latest --project "$TEST_PROJECT" --secret="$secret_name")
208+
echo "export $env_var_name='$val'"
209+
done
210+
} > "$1"
211+
212+
}
213+
214+
## help - prints the help details
215+
##
216+
function help() {
217+
# This will print the comments beginning with ## above each function
218+
# in this file.
219+
220+
echo "build.sh <command> <arguments>"
221+
echo
222+
echo "Commands to assist with local development and CI builds."
223+
echo
224+
echo "Commands:"
225+
echo
226+
grep -e '^##' "$SCRIPT_FILE" | sed -e 's/##/ /'
227+
}
228+
229+
set -euo pipefail
230+
231+
# Check CLI Arguments
232+
if [[ "$#" -lt 1 ]] ; then
233+
help
234+
exit 1
235+
fi
236+
237+
cd "$SCRIPT_DIR"
238+
239+
"$@"
240+

0 commit comments

Comments
 (0)