Skip to content

Commit 02946f4

Browse files
oakrizanjlind23
andauthored
Migrate golang-crossbuild pipeline (#326)
Co-authored-by: Julien Lind <[email protected]>
1 parent b66e5a5 commit 02946f4

File tree

10 files changed

+389
-8
lines changed

10 files changed

+389
-8
lines changed

.buildkite/hooks/pre-command

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
source .buildkite/scripts/common.sh
6+
7+
DOCKER_REGISTRY_SECRET_PATH="kv/ci-shared/platform-ingest/docker_registry_prod"
8+
PRIVATE_CI_GCS_CREDENTIALS_PATH="kv/ci-shared/platform-ingest/private_ci_artifacts_gcs_credentials"
9+
GITHUB_TOKEN_VAULT_PATH="kv/ci-shared/platform-ingest/github_token"
10+
11+
# Secrets must be redacted
12+
# https://buildkite.com/docs/pipelines/managing-log-output#redacted-environment-variables
13+
14+
if [[ "$BUILDKITE_PIPELINE_SLUG" == "golang-crossbuild" && "$BUILDKITE_STEP_KEY" =~ ^build ]]; then
15+
export PRIVATE_CI_GCS_CREDENTIALS_SECRET=$(retry 5 vault kv get -field plaintext ${PRIVATE_CI_GCS_CREDENTIALS_PATH})
16+
fi
17+
18+
if [[ "$BUILDKITE_PIPELINE_SLUG" == "golang-crossbuild" && ("$BUILDKITE_STEP_KEY" =~ ^build || "$BUILDKITE_STEP_KEY" =~ ^publish)]]; then
19+
export DOCKER_USERNAME_SECRET=$(retry 5 vault kv get -field user "${DOCKER_REGISTRY_SECRET_PATH}")
20+
export DOCKER_PASSWORD_SECRET=$(retry 5 vault kv get -field password "${DOCKER_REGISTRY_SECRET_PATH}")
21+
docker login -u "${DOCKER_USERNAME_SECRET}" -p "${DOCKER_PASSWORD_SECRET}" "${DOCKER_REGISTRY}" 2>/dev/null
22+
fi
23+
24+
if [[ "$BUILDKITE_PIPELINE_SLUG" == "golang-crossbuild" && "$BUILDKITE_STEP_KEY" == "post-release" ]]; then
25+
export GITHUB_TOKEN_SECRET=$(retry 5 vault kv get -field token ${GITHUB_TOKEN_VAULT_PATH})
26+
export GITHUB_USERNAME_SECRET=$(retry 5 vault kv get -field username ${GITHUB_TOKEN_VAULT_PATH})
27+
export GITHUB_EMAIL_SECRET=$(retry 5 vault kv get -field email ${GITHUB_TOKEN_VAULT_PATH})
28+
fi

.buildkite/hooks/pre-exit

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
source .buildkite/scripts/common.sh
6+
7+
unset_secrets
8+
9+
if [[ "$BUILDKITE_PIPELINE_SLUG" == "golang-crossbuild" && "$BUILDKITE_STEP_KEY" =~ ^build ]]; then
10+
google_cloud_logout_active_account
11+
fi
12+
13+
if [[ "$BUILDKITE_PIPELINE_SLUG" == "golang-crossbuild" && ("$BUILDKITE_STEP_KEY" =~ ^build || "$BUILDKITE_STEP_KEY" =~ ^publish) ]]; then
14+
docker logout "${DOCKER_REGISTRY}"
15+
fi
16+
17+
# Ensure that any temporal files created during any step are removed
18+
cleanup

.buildkite/pipeline.yml

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,114 @@
11
# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json
22

3+
env:
4+
SETUP_GVM_VERSION: "v0.5.1"
5+
GOLANG_VERSION: "1.21.3"
6+
IMAGE_UBUNTU_X86_64: "family/core-ubuntu-2204"
7+
IMAGE_UBUNTU_ARM_64: "core-ubuntu-2004-aarch64"
8+
DOCKER_REGISTRY: "docker.elastic.co"
9+
STAGING_IMAGE: "${DOCKER_REGISTRY}/observability-ci"
10+
DOCKER_REGISTRY_SECRET_PATH: "secret/observability-team/ci/docker-registry/prod"
11+
BUILDX: 1
12+
313
steps:
4-
- label: "Example test"
5-
command: echo "Hello!"
14+
- group: "Staging"
15+
key: "staging"
16+
17+
steps:
18+
- label: ":linux: Staging / Ubuntu X86_64 - {{matrix.makefile}}"
19+
key: "build-ubuntu-x86"
20+
command:
21+
- ".buildkite/scripts/build.sh {{matrix.makefile}}"
22+
- ".buildkite/scripts/publish.sh {{matrix.makefile}}"
23+
if: build.env("BUILDKITE_PULL_REQUEST") != "false"
24+
notify:
25+
- github_commit_status:
26+
context: "Staging / Ubuntu X86_64"
27+
agents:
28+
provider: "gcp"
29+
image: "${IMAGE_UBUNTU_X86_64}"
30+
matrix:
31+
setup:
32+
makefile:
33+
- "Makefile"
34+
- "Makefile.debian7"
35+
- "Makefile.debian8"
36+
- "Makefile.debian9"
37+
- "Makefile.debian10"
38+
- "Makefile.debian11"
39+
- "Makefile.debian12"
40+
41+
- label: ":linux: Staging / Ubuntu ARM - Makefile.debian9"
42+
key: "build-ubuntu-arm"
43+
command:
44+
- ".buildkite/scripts/build.sh Makefile.debian9"
45+
- ".buildkite/scripts/publish.sh Makefile.debian9"
46+
env:
47+
REPOSITORY: "${STAGING_IMAGE}"
48+
if: build.env("BUILDKITE_PULL_REQUEST") != "false"
49+
notify:
50+
- github_commit_status:
51+
context: "Staging / Ubuntu ARM"
52+
agents:
53+
provider: "aws"
54+
imagePrefix: "${IMAGE_UBUNTU_ARM_64}"
55+
instanceType: "t4g.large"
56+
57+
- group: "Release"
58+
key: "release"
59+
notify:
60+
- github_commit_status:
61+
context: "Release / Ubuntu X86_64 && ARM"
62+
63+
steps:
64+
- label: ":linux: Release / Ubuntu X86_64 - {{matrix.makefile}}"
65+
key: "release-ubuntu-x86"
66+
command:
67+
- ".buildkite/scripts/build.sh {{matrix.makefile}}"
68+
- ".buildkite/scripts/publish.sh {{matrix.makefile}}"
69+
branches: "^(main|\\d+\\.\\d+)$"
70+
agents:
71+
provider: "gcp"
72+
image: "${IMAGE_UBUNTU_X86_64}"
73+
matrix:
74+
setup:
75+
makefile:
76+
- "Makefile"
77+
- "Makefile.debian7"
78+
- "Makefile.debian8"
79+
- "Makefile.debian9"
80+
- "Makefile.debian10"
81+
- "Makefile.debian11"
82+
- "Makefile.debian12"
83+
84+
- label: ":linux: Release / Ubuntu ARM - {{matrix.makefile}}"
85+
key: "release-ubuntu-arm"
86+
command:
87+
- ".buildkite/scripts/build.sh {{matrix.makefile}}"
88+
- ".buildkite/scripts/publish.sh {{matrix.makefile}}"
89+
branches: "^(main|\\d+\\.\\d+)$"
90+
agents:
91+
provider: "aws"
92+
imagePrefix: "${IMAGE_UBUNTU_ARM_64}"
93+
instanceType: "t4g.large"
94+
matrix:
95+
setup:
96+
makefile:
97+
- "Makefile"
98+
- "Makefile.debian7"
99+
- "Makefile.debian8"
100+
- "Makefile.debian9"
101+
- "Makefile.debian10"
102+
- "Makefile.debian11"
103+
- "Makefile.debian12"
104+
105+
- label: "Post-Release"
106+
key: "post-release"
107+
command: ".buildkite/scripts/post-release.sh ${GOLANG_VERSION}"
108+
branches: "^(main|\\d+\\.\\d+)$"
109+
notify:
110+
- github_commit_status:
111+
context: "Post-release"
112+
agents:
113+
provider: "gcp"
114+
image: "${IMAGE_UBUNTU_X86_64}"

.buildkite/scripts/build.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
source .buildkite/scripts/common.sh
6+
7+
MAKEFILE=${1}
8+
9+
check_is_arm
10+
11+
add_bin_path
12+
with_go "${GOLANG_VERSION}"
13+
with_mage
14+
google_cloud_auth
15+
16+
make -C go -f "${MAKEFILE}" build"${is_arm}" GS_BUCKET_PATH=ingest-buildkite-ci
17+
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" --filter=reference="${STAGING_IMAGE}/golang-crossbuild"
18+
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" --filter=reference="${DOCKER_REGISTRY}/beats-dev/golang-crossbuild"
19+
20+

.buildkite/scripts/buildx.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
set +x
4+
5+
BUILDPLATFORM=${BUILDPLATFORM:-"linux/amd64,linux/arm64"}
6+
7+
#docker run --privileged --rm tonistiigi/binfmt --install all
8+
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
9+
BUILDER_NAME="multibuilder${RANDOM}"
10+
echo "Add support for multiarch"
11+
docker run --privileged --rm tonistiigi/binfmt --install all
12+
13+
docker buildx ls
14+
echo 'Create builder'
15+
docker buildx create --name "${BUILDER_NAME}"
16+
docker buildx use "${BUILDER_NAME}"
17+
docker buildx inspect --bootstrap
18+
echo 'Build Docker image'
19+
docker buildx build --platform "${BUILDPLATFORM}" --push $*

.buildkite/scripts/common.sh

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
REPO="golang-crossbuild"
6+
WORKSPACE="$(pwd)/bin"
7+
HW_TYPE="$(uname -m)"
8+
PLATFORM_TYPE="$(uname)"
9+
TMP_FOLDER="tmp.${REPO}"
10+
GOOGLE_CREDENTIALS_FILENAME="google-cloud-credentials.json"
11+
12+
add_bin_path() {
13+
echo "Adding PATH to the environment variables..."
14+
create_workspace
15+
export PATH="${PATH}:${WORKSPACE}"
16+
}
17+
18+
with_go() {
19+
local go_version="${1}"
20+
echo "Setting up the Go environment..."
21+
create_workspace
22+
check_platform_architecture
23+
retry 5 curl -sL -o ${WORKSPACE}/gvm "https://github.com/andrewkroh/gvm/releases/download/${SETUP_GVM_VERSION}/gvm-${PLATFORM_TYPE}-${arch_type}"
24+
export PATH="${PATH}:${WORKSPACE}"
25+
chmod +x ${WORKSPACE}/gvm
26+
eval "$(gvm "$go_version")"
27+
go version
28+
which go
29+
export PATH="${PATH}:$(go env GOPATH):$(go env GOPATH)/bin"
30+
}
31+
32+
with_mage() {
33+
local install_packages=(
34+
"github.com/magefile/mage"
35+
"github.com/elastic/go-licenser"
36+
"golang.org/x/tools/cmd/goimports"
37+
"github.com/jstemmer/go-junit-report"
38+
"gotest.tools/gotestsum"
39+
)
40+
create_workspace
41+
for pkg in "${install_packages[@]}"; do
42+
go install "${pkg}@latest"
43+
done
44+
}
45+
46+
create_workspace() {
47+
if [[ ! -d "${WORKSPACE}" ]]; then
48+
mkdir -p ${WORKSPACE}
49+
fi
50+
}
51+
52+
check_platform_architecture() {
53+
# for downloading the GVM and Terraform packages
54+
case "${HW_TYPE}" in
55+
"x86_64")
56+
arch_type="amd64"
57+
;;
58+
"aarch64")
59+
arch_type="arm64"
60+
;;
61+
"arm64")
62+
arch_type="arm64"
63+
;;
64+
*)
65+
echo "The current platform/OS type is unsupported yet"
66+
;;
67+
esac
68+
}
69+
70+
retry() {
71+
local retries=$1
72+
shift
73+
local count=0
74+
until "$@"; do
75+
exit=$?
76+
wait=$((2 ** count))
77+
count=$((count + 1))
78+
if [ $count -lt "$retries" ]; then
79+
>&2 echo "Retry $count/$retries exited $exit, retrying in $wait seconds..."
80+
sleep $wait
81+
else
82+
>&2 echo "Retry $count/$retries exited $exit, no more retries left."
83+
return $exit
84+
fi
85+
done
86+
return 0
87+
}
88+
89+
google_cloud_auth() {
90+
local gsUtilLocation=$(mktemp -d -p ${WORKSPACE} -t "${TMP_FOLDER}.XXXXXXXXX")
91+
local secretFileLocation=${gsUtilLocation}/${GOOGLE_CREDENTIALS_FILENAME}
92+
echo "${PRIVATE_CI_GCS_CREDENTIALS_SECRET}" > ${secretFileLocation}
93+
gcloud auth activate-service-account --key-file ${secretFileLocation} 2> /dev/null
94+
export GOOGLE_APPLICATION_CREDENTIALS=${secretFileLocation}
95+
}
96+
97+
unset_secrets () {
98+
for var in $(printenv | sed 's;=.*;;' | sort); do
99+
if [[ "$var" == *_SECRET || "$var" == *_TOKEN ]]; then
100+
unset "$var"
101+
fi
102+
done
103+
}
104+
105+
google_cloud_logout_active_account() {
106+
local active_account=$(gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null)
107+
if [[ -n "$active_account" && -n "${GOOGLE_APPLICATION_CREDENTIALS+x}" ]]; then
108+
echo "Logging out from GCP for active account"
109+
gcloud auth revoke $active_account > /dev/null 2>&1
110+
else
111+
echo "No active GCP accounts found."
112+
fi
113+
if [ -n "${GOOGLE_APPLICATION_CREDENTIALS+x}" ]; then
114+
unset GOOGLE_APPLICATION_CREDENTIALS
115+
cleanup
116+
fi
117+
}
118+
119+
cleanup() {
120+
echo "Deleting temporary files..."
121+
rm -rf ${WORKSPACE}/${TMP_FOLDER}.*
122+
echo "Done."
123+
}
124+
125+
tag_Exists() {
126+
local tag=$1
127+
local url=https://api.github.com/repos/elastic/${REPO}/releases/tags/${tag}
128+
local status=$(retry 3 curl -s -o /dev/null -w "%{http_code}" -u ${GITHUB_TOKEN_SECRET}:x-oauth-basic ${url})
129+
130+
if [ "${status}" == "200" ]; then
131+
echo true
132+
else
133+
echo false
134+
fi
135+
}
136+
137+
check_is_arm() {
138+
if [[ ${HW_TYPE} == "aarch64" || ${HW_TYPE} == "arm64" ]]; then
139+
is_arm="-arm"
140+
else
141+
is_arm=""
142+
fi
143+
}

.buildkite/scripts/post-release.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
source .buildkite/scripts/common.sh
6+
7+
TAG="v{$1}"
8+
TAG_EXISTS=$(tag_Exists ${TAG})
9+
10+
set_git_config() {
11+
git config user.name "${GITHUB_USERNAME_SECRET}"
12+
git config user.email "${GITHUB_EMAIL_SECRET}"
13+
}
14+
15+
tag_commit() {
16+
echo "Tagging commit ${BUILDKITE_COMMIT}"
17+
git tag -a -m "${BUILDKITE_COMMIT}" "${TAG}"
18+
}
19+
20+
git_push_with_auth() {
21+
echo "Pushing tag ${TAG}"
22+
retry 3 git push https://${GITHUB_USERNAME_SECRET}:${GITHUB_TOKEN_SECRET}@github.com/elastic/golang-crossbuild.git ${TAG}
23+
}
24+
25+
if [[ "${TAG_EXISTS}" == true ]]; then
26+
echo "Tag already exists! Exiting Post-release stage."
27+
exit 1
28+
fi
29+
30+
set_git_config
31+
tag_commit
32+
git_push_with_auth
33+
34+

.buildkite/scripts/publish.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
source .buildkite/scripts/common.sh
6+
7+
MAKEFILE=${1}
8+
9+
check_is_arm
10+
add_bin_path
11+
retry 3 make -C go -f "${MAKEFILE}" push"${is_arm}"

0 commit comments

Comments
 (0)