Skip to content

Commit

Permalink
Rework build_and_publish.yaml to handle docker images (#951)
Browse files Browse the repository at this point in the history
  • Loading branch information
mem authored Oct 19, 2024
1 parent f461094 commit 7189a16
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 66 deletions.
1 change: 1 addition & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ self-hosted-runner:
- ubuntu-amd64
- ubuntu-arm64
- github-hosted-ubuntu-arm64
- github-hosted-ubuntu-x64-small

# Configuration variables in array of strings defined in your repository or
# organization. `null` means disabling configuration variables check.
Expand Down
127 changes: 73 additions & 54 deletions .github/workflows/build_and_publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,28 @@ jobs:
if: ${{ always() && needs.preflight.result == 'success' }}
strategy:
matrix:
arch: [ x64-small, arm64 ]
arch: [ x64-large, arm64 ]
runs-on: github-hosted-ubuntu-${{ matrix.arch }}

container:
image: ghcr.io/grafana/grafana-build-tools:v0.24.0@sha256:309c71f542b53fcb5fbc9042ec45cbab881a3b310c3a57b843d8ffe979bfa951
# --user is needed so that it's possible to access the git directory.
# --group-add is needed so that it's possible to access the docker socket.
#
# ubuntu-latest and github-hosted-ubuntu-arm64 have different group ids for the docker socket.
#
# This works for GitHub runners
options: --user 1001:118 --group-add 116
# This works for self-hosted runners; 126 is the group for the docker socket.
# options: --user 1000:126
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
outputs:
version: ${{ steps.version.outputs.value }}

steps:
- name: checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
fetch-depth: 0
fetch-tags: true

- name: Set up global git config
run: |
# The directory where the code has been checked out ends up belonging
# to a different user, so git complains about permissions. Indicate
# that it's safe to ignore.
git config --global --add safe.directory '*'
- name: Restore Go cache
id: restore-go-cache
uses: ./.github/actions/go-cache-restore
Expand Down Expand Up @@ -87,30 +83,45 @@ jobs:
- name: test
run: make test

- name: test docker build
uses: grafana/shared-workflows/actions/build-push-to-dockerhub@f0dd3480fa3e657d741dd9e8d9b999cfb61fc713
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1

- name: build docker image (no browser)
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: .
push: false
platforms: |-
${{ steps.build-info.outputs.os }}/${{ steps.build-info.outputs.arch }}
tags: |-
type=raw,value=${{ steps.version.outputs.value }}
type=sha,prefix=sha-,format=short
latest
file: Dockerfile.build
target: release
outputs: type=tar,dest=dist/container-image.no-browser.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar
cache-from: type=gha
cache-to: type=gha,mode=max

- name: build docker image (browser)
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: .
push: false
file: Dockerfile.build
target: with-browser
outputs: type=tar,dest=dist/container-image.browser.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar
cache-from: type=gha
cache-to: type=gha,mode=max

- name: create build artifacts
- name: create build artfact
run: |
# Create a tarball of the build artifacts to preserve permissions and
# the directory structure. The actions/upload-artifact action will
# create a zip file, which cannot preserve all this information.
tar -C dist -cf 'dist/build-artifacts-${{ steps.build-info.outputs.arch }}.tar' 'linux-${{ steps.build-info.outputs.arch }}'
tar cf dist/build-artifacts.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar \
dist/container-image.*.*.tar \
dist/${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}
- name: upload build artifacts
- name: upload build artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
with:
name: build-artifacts-${{ steps.build-info.outputs.arch }}
path: dist/build-artifacts-${{ steps.build-info.outputs.arch }}.tar
name: build-artifacts-${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}
path: dist/build-artifacts.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar
retention-days: 1
if-no-files-found: error
overwrite: false

- name: Save Go cache
id: save-go-cache
Expand All @@ -125,7 +136,7 @@ jobs:
- preflight
- validate
if: ${{ always() && needs.validate.result == 'success' && needs.preflight.result == 'success' }}
runs-on: ubuntu-amd64
runs-on: github-hosted-ubuntu-x64-small
outputs:
image_name: ${{ steps.extract-image-metadata.outputs.image }}
image_version: ${{ steps.extract-image-metadata.outputs.tag }}
Expand All @@ -135,6 +146,13 @@ jobs:
with:
fetch-depth: 0

- name: Set up global git config
run: |
# The directory where the code has been checked out ends up belonging
# to a different user, so git complains about permissions. Indicate
# that it's safe to ignore.
git config --global --add safe.directory '*'
- name: download build artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
with:
Expand All @@ -145,39 +163,26 @@ jobs:
id: extract-build-artifacts
# Note that the download-artifact action will create a directory for
# each artifact that it downloads, named afer the artifact's name.
# That's the `build-artifacts-*` portion of the path. The wildcard
# refers to the architecture of the binaries. The artifact itself
# consists of a single file, a tarball, and it's also named
# `build-artifacts-*`. The tarball contains the linux-arch directory,
# so everything is extracted directly to the dist directory.
# That's the `build-artifacts-*` portion of the path.
#
# After extracting all the artifacts, this builds an output named
# `platforms` that lists all the platforms that are available. This is
# used by the step that builds the docker images to tell it what
# platforms should be included.
run: |
find dist/build-artifacts-*/build-artifacts-*.tar -print0 | xargs -r0 -n1 -I{} tar -xvpf {} -C dist
find dist/build-artifacts-*/build-artifacts.*.tar -print0 |
xargs -r0 -I{} tar -xvpf {}
{
echo 'platforms<<EOT'
find dist/linux-* -maxdepth 0 -type d -print0 | xargs -r0 -n1 basename | tr - /
find dist/ -maxdepth 1 -name 'container-image.*.*.tar' -print0 |
xargs -r0 -n1 basename |
cut -d. -f3 |
tr - /
echo 'EOT'
} >> "$GITHUB_OUTPUT"
- name: Get repository name
env:
REPOSITORY: ${{ github.repository }}
id: info
run: |
case ${{ inputs.mode }} in
dev)
echo "tag=sha-${{ github.sha }}" >> "$GITHUB_OUTPUT"
;;
prod)
echo "tag=latest" >> "$GITHUB_OUTPUT"
;;
esac
- name: push container images to GAR
- name: push container images to GAR (no browser)
id: push-to-gar
uses: grafana/shared-workflows/actions/push-to-gar-docker@f0dd3480fa3e657d741dd9e8d9b999cfb61fc713
with:
Expand All @@ -189,6 +194,20 @@ jobs:
type=raw,value=${{ needs.validate.outputs.version }}
type=sha,prefix=sha-,format=short
latest
file: Dockerfile.no-browser

- name: push container images to GAR (browser)
uses: grafana/shared-workflows/actions/push-to-gar-docker@f0dd3480fa3e657d741dd9e8d9b999cfb61fc713
with:
environment: ${{ inputs.mode }}
image_name: ${{ needs.preflight.outputs.repo_name }}
push: true
platforms: ${{ steps.extract-build-artifacts.outputs.platforms }}
tags: |-
type=raw,value=${{ needs.validate.outputs.version }}-browser
type=sha,prefix=sha-,suffix=-browser,format=short
latest-browser
file: Dockerfile.browser

- name: extract image metadata
id: extract-image-metadata
Expand All @@ -205,7 +224,7 @@ jobs:
- preflight
- publish_images
if: ${{ always() && needs.publish_images.result == 'success' && needs.preflight.result == 'success' }}
runs-on: ubuntu-amd64
runs-on: github-hosted-ubuntu-x64-small
steps:
# The following two steps are needed because trigger-argo-workflow is
# calling setup-go *after* setup-argo, and setup-argo actually needs go
Expand Down
12 changes: 1 addition & 11 deletions .github/workflows/validate_pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ jobs:
runner: [ ubuntu-latest, github-hosted-ubuntu-arm64 ]
runs-on: ${{ matrix.runner }}

# The service is needed so that we can run docker in order to create
# images. Since we are already running in a container, we need to run
# docker in docker.
services:
docker:
image: docker:20.10.8-dind
options: --privileged
ports:
- 2375:2375

container:
image: ghcr.io/grafana/grafana-build-tools:v0.24.0@sha256:309c71f542b53fcb5fbc9042ec45cbab881a3b310c3a57b843d8ffe979bfa951

Expand All @@ -38,7 +28,7 @@ jobs:
# The directory where the code has been checked out ends up belonging
# to a different user, so git complains about permissions. Indicate
# that it's safe to ignore.
git config --global --add safe.directory "$PWD"
git config --global --add safe.directory '*'
- name: Restore Go cache
id: restore-go-cache
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ FROM --platform=$TARGETPLATFORM alpine:3.20.3 AS with-browser
# The --repository arg is required for renovate to know which alpine repo it should look for updates in.
# To keep the renovate regex simple, only keep one package installation per line.
RUN apk --no-cache add --repository community tini=0.19.0-r3 && \
apk --no-cache add --repository community chromium-swiftshader=129.0.6668.89-r0
apk --no-cache add --repository community chromium-swiftshader=130.0.6723.58-r0

COPY --from=release /usr/local/bin/synthetic-monitoring-agent /usr/local/bin/synthetic-monitoring-agent
COPY --from=release /usr/local/bin/sm-k6 /usr/local/bin/sm-k6
Expand Down
10 changes: 10 additions & 0 deletions Dockerfile.browser
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM --platform=$TARGETOS/$TARGETARCH scratch

ARG TARGETOS
ARG TARGETARCH

ADD ./dist/container-image.browser.${TARGETOS}-${TARGETARCH}.tar /

ENV K6_BROWSER_ARGS=no-sandbox,disable-dev-shm-usage

ENTRYPOINT ["tini", "--", "/usr/local/bin/synthetic-monitoring-agent"]
37 changes: 37 additions & 0 deletions Dockerfile.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# First stage obtains the list of certificates.
FROM --platform=$BUILDPLATFORM alpine:3.20.3 AS build
RUN apk --no-cache add ca-certificates-bundle

# Second stage copies the binaries, configuration and also the
# certificates from the first stage.

FROM alpine:3.20.3 AS release
ARG TARGETOS
ARG TARGETARCH
ARG HOST_DIST=$TARGETOS-$TARGETARCH

COPY dist/${HOST_DIST}/synthetic-monitoring-agent /usr/local/bin/synthetic-monitoring-agent
COPY dist/${HOST_DIST}/k6 /usr/local/bin/sm-k6
COPY scripts/pre-stop.sh /usr/local/lib/synthetic-monitoring-agent/pre-stop.sh
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

ENTRYPOINT ["/usr/local/bin/synthetic-monitoring-agent"]

# Third stage copies the setup from the base agent and
# additionally installs Chromium to support browser checks.
FROM alpine:3.20.3 AS with-browser

# Renovate updates the pinned packages below.
# The --repository arg is required for renovate to know which alpine repo it should look for updates in.
# To keep the renovate regex simple, only keep one package installation per line.
RUN apk --no-cache add --repository community tini=0.19.0-r3
RUN apk --no-cache add --repository community chromium-swiftshader=130.0.6723.58-r0

COPY --from=release /usr/local/bin/synthetic-monitoring-agent /usr/local/bin/synthetic-monitoring-agent
COPY --from=release /usr/local/bin/sm-k6 /usr/local/bin/sm-k6
COPY --from=release /usr/local/lib/synthetic-monitoring-agent/pre-stop.sh /usr/local/lib/synthetic-monitoring-agent/pre-stop.sh
COPY --from=release /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

ENV K6_BROWSER_ARGS=no-sandbox,disable-dev-shm-usage

ENTRYPOINT ["tini", "--", "/usr/local/bin/synthetic-monitoring-agent"]
8 changes: 8 additions & 0 deletions Dockerfile.no-browser
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM --platform=$TARGETOS/$TARGETARCH scratch

ARG TARGETOS
ARG TARGETARCH

ADD ./dist/container-image.no-browser.${TARGETOS}-${TARGETARCH}.tar /

ENTRYPOINT ["/usr/local/bin/synthetic-monitoring-agent"]
11 changes: 11 additions & 0 deletions scripts/export-docker-image
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

set -e
set -u

image_name=$1
output=$2

container_id=$(docker container create "${image_name}")
trap 'docker container rm "${container_id}"' EXIT
docker container export -o "${output}" "${container_id}"
9 changes: 9 additions & 0 deletions scripts/extract-image-info
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

data=$(mktemp)
trap 'rm -f $data' EXIT

cat "$1" > "$data"

echo "image=$(jq -r '.target["docker-metadata-action"].args.DOCKER_META_IMAGES' < "$data")"
echo "tag=$(jq -r '.target["docker-metadata-action"].args.DOCKER_META_VERSION' < "$data")"

0 comments on commit 7189a16

Please sign in to comment.