Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Docker image release #339

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .buildkite/Dockerfile.public
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM public.ecr.aws/docker/library/alpine:3.20.3@sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a
ARG TARGETARCH
RUN apk update && apk add --no-cache curl ca-certificates
COPY dist/buildkite-agent-metrics-linux-${TARGETARCH} ./buildkite-agent-metrics
EXPOSE 8080 8125
ENTRYPOINT ["./buildkite-agent-metrics"]
14 changes: 12 additions & 2 deletions .buildkite/pipeline.release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@ steps:
queue: "elastic-runners"
plugins:
- aws-assume-role-with-web-identity:
role-arn: arn:aws:iam::445615400570:role/pipeline-buildkite-buildkite-agent-metrics
role-arn: arn:aws:iam::445615400570:role/pipeline-buildkite-buildkite-agent-metrics-release
- aws-ssm#v1.0.0:
parameters:
GITHUB_RELEASE_ACCESS_TOKEN: /pipelines/buildkite/buildkite-agent-metrics/GITHUB_RELEASE_ACCESS_TOKEN
GITHUB_RELEASE_ACCESS_TOKEN: /pipelines/buildkite/buildkite-agent-metrics-release/GITHUB_RELEASE_ACCESS_TOKEN
- docker-compose#v5.5.0:
config: .buildkite/docker-compose.yaml
run: release
cli-version: 2
mount-buildkite-agent: true

- label: ":docker: Push"
command: ".buildkite/steps/release-docker.sh"
depends_on:
- block-release
agents:
queue: "elastic-runners"
plugins:
- aws-assume-role-with-web-identity:
role-arn: arn:aws:iam::172840064832:role/pipeline-buildkite-buildkite-agent-metrics-release
19 changes: 16 additions & 3 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
env:
RELEASE_DRY_RUN: false

steps:
- name: ":test_tube: Test"
key: test
Expand Down Expand Up @@ -60,9 +63,19 @@ steps:
- aws-assume-role-with-web-identity:
role-arn: arn:aws:iam::032379705303:role/pipeline-buildkite-buildkite-agent-metrics

- name: ":pipeline:"
key: upload-release-steps
- if: build.env("RELEASE_DRY_RUN") == "true" || build.env("BUILDKITE_TAG") =~ /^v\d+\.\d+\.\d+$$/
name: ":rocket: Release"
key: trigger-release
trigger: "buildkite-agent-metrics-release"
async: false
depends_on:
- build-binary
- upload-to-s3
command: .buildkite/steps/upload-release-steps.sh
build:
message: "Release for ${BUILDKITE_TAG}, build ${BUILDKITE_BUILD_NUMBER}"
commit: "${BUILDKITE_COMMIT}"
branch: "${BUILDKITE_BRANCH}"
meta_data:
metrics-artifacts-build: "${BUILDKITE_BUILD_ID}"
env:
RELEASE_DRY_RUN: "${RELEASE_DRY_RUN:-false}"
89 changes: 89 additions & 0 deletions .buildkite/steps/release-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env bash

set -Eeufo pipefail

source .buildkite/lib/release_dry_run.sh

if [[ "${RELEASE_DRY_RUN:-false}" != "true" && "${BUILDKITE_BRANCH}" != "${BUILDKITE_TAG:-}" ]]; then
echo "Skipping release for a non-tag build on ${BUILDKITE_BRANCH}" >&2
exit 0
fi

registry="public.ecr.aws/buildkite/agent-metrics"
image_tag="${registry}:build-${BUILDKITE_BUILD_NUMBER}"

echo --- Fetching tags
git fetch --prune --force origin "+refs/tags/*:refs/tags/*"

echo --- Checking tags
version="$(awk -F\" '/const Version/ {print $2}' version/version.go)"
tag="v${version#v}"

if [[ "${RELEASE_DRY_RUN:-false}" != true && "${tag}" != "${BUILDKITE_TAG}" ]]; then
echo "Error: version.go has not been updated to ${BUILDKITE_TAG#v}"
exit 1
fi

echo --- Downloading binaries

artifacts_build="$(buildkite-agent meta-data get "metrics-artifacts-build")"

rm -rf dist
mkdir -p dist
buildkite-agent artifact download --build "${artifacts_build}" "dist/buildkite-agent-metrics-linux-*" ./dist

echo "--- Building :docker: image"

builder_name="$(docker buildx create --use)"
# shellcheck disable=SC2064 # we want the current $builder_name to be trapped, not the runtime one
trap "docker buildx rm ${builder_name} || true" EXIT

echo "--- Building :docker: ${image_tag} for all architectures"
docker buildx build \
--progress plain \
--builder "${builder_name}" \
--platform linux/amd64,linux/arm64 \
--file .buildkite/Dockerfile.public \
.

# Tag images for just the native architecture. There is a limitation in docker that prevents this
# from being done in one command. Luckliy the second build will be quick because of docker layer caching
# As this is just a native build, we don't need the lock.
docker buildx build \
--progress plain \
--builder "${builder_name}" \
--tag "${image_tag}" \
--file .buildkite/Dockerfile.public \
--load \
.

echo --- :ecr: Pushing to ECR

# Convert 2.3.2 into [ 2.3.2 2.3 2 ] or 3.0-beta.42 in [ 3.0-beta.42 3.0 3 ]
parse_version() {
local v="$1"
IFS='.' read -r -a parts <<< "${v%-*}"

for idx in $(seq 1 ${#parts[*]}) ; do
sed -e 's/ /./g' <<< "${parts[@]:0:$idx}"
done

[[ "${v%-*}" == "${v}" ]] || echo "${v}"
}

version_tags=($(parse_version "${version#v}"))

# Do another build with all architectures and tags. The layers should be cached
# from the previous build with all architectures.
# Pushing to the docker registry in this way greatly simplifies creating the
# manifest list on the docker registry so that either architecture can be pulled
# with the same tag.
release_dry_run docker buildx build \
--progress plain \
--builder "${builder_name}" \
--tag "${registry}:latest" \
"${version_tags[@]/#/--tag ${registry}:v}" \
--platform linux/amd64,linux/arm64 \
--file .buildkite/Dockerfile.public \
--push \
.
30 changes: 19 additions & 11 deletions .buildkite/steps/release-github.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ set -eufo pipefail

source .buildkite/lib/release_dry_run.sh

if [[ "$GITHUB_RELEASE_ACCESS_TOKEN" == "" ]]; then
if [[ "${RELEASE_DRY_RUN:-false}" != "true" && "${BUILDKITE_BRANCH}" != "${BUILDKITE_TAG:-}" ]]; then
echo "Skipping release for a non-tag build on ${BUILDKITE_BRANCH}" >&2
exit 0
fi

if [[ "${GITHUB_RELEASE_ACCESS_TOKEN}" == "" ]]; then
echo "Error: Missing \$GITHUB_RELEASE_ACCESS_TOKEN" >&2
exit 1
fi
Expand All @@ -13,27 +18,30 @@ echo --- Fetching tags
git fetch --prune --force origin "+refs/tags/*:refs/tags/*"

echo --- Downloading binaries

artifacts_build="$(buildkite-agent meta-data get "metrics-artifacts-build")"

rm -rf dist
mkdir -p dist
buildkite-agent artifact download "dist/*" ./dist
buildkite-agent artifact download --build "${artifacts_build}" "dist/*" ./dist

echo --- Checking tags
version=$(awk -F\" '/const Version/ {print $2}' version/version.go)
version="$(awk -F\" '/const Version/ {print $2}' version/version.go)"
tag="v${version#v}"

if [[ "${RELEASE_DRY_RUN:-false}" != true && $tag != "$BUILDKITE_TAG" ]]; then
if [[ "${RELEASE_DRY_RUN:-false}" != true && "${tag}" != "${BUILDKITE_TAG}" ]]; then
echo "Error: version.go has not been updated to ${BUILDKITE_TAG#v}"
exit 1
fi

last_tag=$(git describe --tags --abbrev=0 --exclude "$tag")
last_tag=$(git describe --tags --abbrev=0 --exclude "${tag}")

# escape . so we can use in regex
escaped_tag="${tag//\./\\.}"
escaped_last_tag="${last_tag//\./\\.}"

if [[ "${RELEASE_DRY_RUN:-false}" != true ]] && ! grep "^## \[$escaped_tag\]" CHANGELOG.md; then
echo "Error: CHANGELOG.md has not been updated for $tag" >&2
if [[ "${RELEASE_DRY_RUN:-false}" != true ]] && ! grep "^## \[${escaped_tag}\]" CHANGELOG.md; then
echo "Error: CHANGELOG.md has not been updated for ${tag}" >&2
exit 1
fi

Expand All @@ -52,16 +60,16 @@ echo --- The following notes will accompany the release:
notes=$(sed -n "/^## \[${escaped_tag}\]/,/^## \[${escaped_last_tag}\]/p" CHANGELOG.md | sed '$d')

echo --- The following notes will accompany the release:
echo "$notes"
echo "${notes}"

echo --- :github: Publishing draft release
# TODO: add the following flag once github-cli in alpine repo hits v2.27+
# --verify-tag \
set +f
GITHUB_TOKEN="$GITHUB_RELEASE_ACCESS_TOKEN" \
GITHUB_TOKEN="${GITHUB_RELEASE_ACCESS_TOKEN}" \
release_dry_run gh release create \
--draft \
--notes "$notes" \
"$tag" \
--notes "${notes}" \
"${tag}" \
dist/*
set -f
5 changes: 5 additions & 0 deletions .buildkite/steps/release-s3-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ set -euo pipefail

source .buildkite/lib/release_dry_run.sh

if [[ "${RELEASE_DRY_RUN:-false}" != "true" && "${BUILDKITE_BRANCH}" != "${BUILDKITE_TAG:-}" ]]; then
echo "Skipping release for a non-tag build on ${BUILDKITE_BRANCH}" >&2
exit 0
fi

release_dry_run .buildkite/steps/upload-to-s3.sh release
9 changes: 0 additions & 9 deletions .buildkite/steps/upload-release-steps.sh

This file was deleted.

11 changes: 7 additions & 4 deletions .buildkite/steps/upload-to-s3.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -eu

export AWS_DEFAULT_REGION=us-east-1
export AWS_DEFAULT_REGION="us-east-1"

# Updated from https://docs.aws.amazon.com/general/latest/gr/rande.html#lambda_region
EXTRA_REGIONS=(
Expand All @@ -26,8 +26,8 @@ EXTRA_REGIONS=(
sa-east-1
)

VERSION=$(awk -F\" '/const Version/ {print $2}' version/version.go)
BASE_BUCKET=buildkite-lambdas
VERSION="$(awk -F\" '/const Version/ {print $2}' version/version.go)"
BASE_BUCKET="buildkite-lambdas"
BUCKET_PATH="buildkite-agent-metrics"

if [[ "${1:-}" == "release" ]] ; then
Expand All @@ -37,8 +37,11 @@ else
fi

echo "~~~ :buildkite: Downloading artifacts"

artifacts_build="$(buildkite-agent meta-data get "metrics-artifacts-build")"

mkdir -p dist
buildkite-agent artifact download dist/handler.zip ./dist
buildkite-agent artifact download --build "${artifacts_build}" dist/handler.zip ./dist

echo "--- :s3: Uploading lambda to ${BASE_BUCKET}/${BUCKET_PATH}/ in ${AWS_DEFAULT_REGION}"
aws s3 cp --acl public-read dist/handler.zip "s3://${BASE_BUCKET}/${BUCKET_PATH}/handler.zip"
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Use this Dockerfile when building the image yourself.
# The Buildkite pipeline is similar, but copies prebuilt binaries instead of
# rebuilding them.
FROM public.ecr.aws/docker/library/golang:1.23.3@sha256:73f06be4578c9987ce560087e2e2ea6485fb605e3910542cadd8fa09fc5f3e31 AS builder
WORKDIR /go/src/github.com/buildkite/buildkite-agent-metrics/
COPY . .
Expand Down