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

Rework build_and_publish.yaml to handle docker images #951

Merged
merged 1 commit into from
Oct 19, 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
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 @@ -7,7 +7,7 @@

ARG TARGETPLATFORM

FROM --platform=$TARGETPLATFORM alpine:3.20.3 AS release

Check warning on line 10 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (ubuntu-latest)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 10 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (ubuntu-latest)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 10 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (github-hosted-ubuntu-arm64)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 10 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (github-hosted-ubuntu-arm64)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/
ARG TARGETOS
ARG TARGETARCH
ARG HOST_DIST=$TARGETOS-$TARGETARCH
Expand All @@ -21,13 +21,13 @@

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

Check warning on line 24 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (ubuntu-latest)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 24 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (ubuntu-latest)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 24 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (github-hosted-ubuntu-arm64)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

Check warning on line 24 in Dockerfile

View workflow job for this annotation

GitHub Actions / validate (github-hosted-ubuntu-arm64)

Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior

RedundantTargetPlatform: Setting platform to predefined $TARGETPLATFORM in FROM is redundant as this is the default behavior More info: https://docs.docker.com/go/dockerfile/rule/redundant-target-platform/

# 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 && \
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")"
Loading