From 360d183b83b18471a702d326a2a94dd85054ae26 Mon Sep 17 00:00:00 2001
From: Carles Garcia Cabot <carles.garciacabot@grafana.com>
Date: Thu, 2 Jan 2025 14:01:53 +0100
Subject: [PATCH] Migrate tempo components docker workflow from Drone to GHA

This includes building the binaries, building and pushing the docker images
to Dockerhub, and updating deployment-tools so tempo-dev-01 uses the latest images.
---
 .drone/drone.jsonnet         | 149 -------------------
 .drone/drone.yml             | 271 +----------------------------------
 .github/workflows/docker.yml | 133 +++++++++++++++++
 3 files changed, 134 insertions(+), 419 deletions(-)
 create mode 100644 .github/workflows/docker.yml

diff --git a/.drone/drone.jsonnet b/.drone/drone.jsonnet
index f3aa2b77845a..18e29f72e3d9 100644
--- a/.drone/drone.jsonnet
+++ b/.drone/drone.jsonnet
@@ -60,158 +60,9 @@ local aws_prod_secret_access_key = secret('AWS_SECRET_ACCESS_KEY-prod', 'infra/d
 // https://github.com/alpine-docker/git/issues/35
 local alpine_git_image = 'alpine/git:v2.30.2';
 
-local image_tag(arch='') = {
-  name: 'image-tag',
-  image: alpine_git_image,
-  commands: [
-    'apk --update --no-cache add bash',
-    'git fetch origin --tags',
-  ] + (
-    if arch == '' then [
-      'echo $(./tools/image-tag) > .tags',
-    ] else [
-      'echo $(./tools/image-tag)-%s > .tags' % arch,
-    ]
-  ),
-};
-
-local image_tag_for_cd() = {
-  name: 'image-tag-for-cd',
-  image: alpine_git_image,
-  commands: [
-    'apk --update --no-cache add bash',
-    'git fetch origin --tags',
-    'echo "grafana/tempo:$(./tools/image-tag)" > .tags-for-cd-tempo',
-    'echo "grafana/tempo-query:$(./tools/image-tag)" > .tags-for-cd-tempo_query',
-    'echo "grafana/tempo-vulture:$(./tools/image-tag)" > .tags-for-cd-tempo_vulture',
-  ],
-};
-
-local build_binaries(arch) = {
-  name: 'build-tempo-binaries',
-  image: 'golang:1.23-alpine',
-  commands: [
-    'apk --update --no-cache add make git bash',
-  ] + [
-    'COMPONENT=%s GOARCH=%s make exe' % [app, arch]
-    for app in apps
-  ],
-};
-
-local docker_build(arch, app, dockerfile='') = {
-  name: 'build-%s-image' % app,
-  image: 'plugins/docker',
-  settings: {
-    dockerfile: if dockerfile != '' then dockerfile else 'cmd/%s/Dockerfile' % app,
-    repo: 'grafana/%s' % app,
-    username: { from_secret: docker_username_secret.name },
-    password: { from_secret: docker_password_secret.name },
-    platform: '%s/%s' % ['linux', arch],
-    build_args: [
-      'TARGETARCH=' + arch,
-    ],
-  },
-};
-
-local docker_manifest(app) = {
-  name: 'manifest-%s' % app,
-  image: 'plugins/manifest:1.4.0',
-  settings: {
-    username: { from_secret: docker_username_secret.name },
-    password: { from_secret: docker_password_secret.name },
-    spec: '.drone/docker-manifest.tmpl',
-    target: app,
-  },
-};
-
-local deploy_to_dev() = {
-  image: 'us.gcr.io/kubernetes-dev/drone/plugins/updater',
-  name: 'update-dev-images',
-  settings: {
-    config_json: std.manifestJsonEx(
-      {
-        destination_branch: 'master',
-        pull_request_branch_prefix: 'auto-merge/cd-tempo-dev',
-        pull_request_enabled: true,
-        pull_request_existing_strategy: "ignore",
-        repo_name: 'deployment_tools',
-        update_jsonnet_attribute_configs: [
-          {
-            file_path: 'ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet',
-            jsonnet_key: app,
-            jsonnet_value_file: '.tags-for-cd-' + app,
-          }
-          for app in ['tempo', 'tempo_query', 'tempo_vulture']
-        ],
-      },
-      '  '
-    ),
-    github_app_id: {
-      from_secret: tempo_app_id_secret.name,
-    },
-    github_app_installation_id: {
-      from_secret: tempo_app_installation_id_secret.name,
-    },
-    github_app_private_key: {
-      from_secret: tempo_app_private_key_secret.name,
-    },
-  },
-};
-
 //# Pipelines & resources
 
 [
-  // A pipeline to build Docker images for every app and for every arch
-  (
-    pipeline('docker-' + arch, arch) {
-      steps+: [
-        image_tag(arch),
-        build_binaries(arch),
-      ] + [
-        docker_build(arch, app)
-        for app in apps
-      ],
-    }
-  )
-  for arch in archs
-] + [
-  // Publish Docker manifests
-  pipeline('manifest') {
-    steps+: [
-      image_tag(),
-    ] + [
-      docker_manifest(app)
-      for app in apps
-    ],
-    depends_on+: [
-      'docker-%s' % arch
-      for arch in archs
-    ],
-  },
-] + [
-  // Continuously Deploy to dev env
-  pipeline('cd-to-dev-env') {
-    trigger: {
-      ref: [
-        // always deploy tip of main to dev
-        'refs/heads/main',
-      ],
-    },
-    image_pull_secrets: [
-      docker_config_json_secret.name,
-    ],
-    steps+: [
-      image_tag_for_cd(),
-    ] + [
-      deploy_to_dev(),
-    ],
-    depends_on+: [
-      // wait for images to be published on dockerhub
-      'manifest',
-    ],
-  },
-] + [
-
   local ghTokenFilename = '/drone/src/gh-token.txt';
   // Build and release packages
   // Tested by installing the packages on a systemd container
diff --git a/.drone/drone.yml b/.drone/drone.yml
index 871c31d0ee3a..34ccebee52fa 100644
--- a/.drone/drone.yml
+++ b/.drone/drone.yml
@@ -1,274 +1,5 @@
 ---
 depends_on: []
-kind: pipeline
-name: docker-amd64
-platform:
-  arch: amd64
-  os: linux
-steps:
-- commands:
-  - apk --update --no-cache add bash
-  - git fetch origin --tags
-  - echo $(./tools/image-tag)-amd64 > .tags
-  image: alpine/git:v2.30.2
-  name: image-tag
-- commands:
-  - apk --update --no-cache add make git bash
-  - COMPONENT=tempo GOARCH=amd64 make exe
-  - COMPONENT=tempo-vulture GOARCH=amd64 make exe
-  - COMPONENT=tempo-query GOARCH=amd64 make exe
-  - COMPONENT=tempo-cli GOARCH=amd64 make exe
-  image: golang:1.23-alpine
-  name: build-tempo-binaries
-- image: plugins/docker
-  name: build-tempo-image
-  settings:
-    build_args:
-    - TARGETARCH=amd64
-    dockerfile: cmd/tempo/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/amd64
-    repo: grafana/tempo
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-vulture-image
-  settings:
-    build_args:
-    - TARGETARCH=amd64
-    dockerfile: cmd/tempo-vulture/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/amd64
-    repo: grafana/tempo-vulture
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-query-image
-  settings:
-    build_args:
-    - TARGETARCH=amd64
-    dockerfile: cmd/tempo-query/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/amd64
-    repo: grafana/tempo-query
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-cli-image
-  settings:
-    build_args:
-    - TARGETARCH=amd64
-    dockerfile: cmd/tempo-cli/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/amd64
-    repo: grafana/tempo-cli
-    username:
-      from_secret: docker_username
-trigger:
-  ref:
-  - refs/heads/main
-  - refs/tags/v*
-  - refs/heads/r?
-  - refs/heads/r??
-  - refs/heads/r???
----
-depends_on: []
-kind: pipeline
-name: docker-arm64
-platform:
-  arch: arm64
-  os: linux
-steps:
-- commands:
-  - apk --update --no-cache add bash
-  - git fetch origin --tags
-  - echo $(./tools/image-tag)-arm64 > .tags
-  image: alpine/git:v2.30.2
-  name: image-tag
-- commands:
-  - apk --update --no-cache add make git bash
-  - COMPONENT=tempo GOARCH=arm64 make exe
-  - COMPONENT=tempo-vulture GOARCH=arm64 make exe
-  - COMPONENT=tempo-query GOARCH=arm64 make exe
-  - COMPONENT=tempo-cli GOARCH=arm64 make exe
-  image: golang:1.23-alpine
-  name: build-tempo-binaries
-- image: plugins/docker
-  name: build-tempo-image
-  settings:
-    build_args:
-    - TARGETARCH=arm64
-    dockerfile: cmd/tempo/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/arm64
-    repo: grafana/tempo
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-vulture-image
-  settings:
-    build_args:
-    - TARGETARCH=arm64
-    dockerfile: cmd/tempo-vulture/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/arm64
-    repo: grafana/tempo-vulture
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-query-image
-  settings:
-    build_args:
-    - TARGETARCH=arm64
-    dockerfile: cmd/tempo-query/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/arm64
-    repo: grafana/tempo-query
-    username:
-      from_secret: docker_username
-- image: plugins/docker
-  name: build-tempo-cli-image
-  settings:
-    build_args:
-    - TARGETARCH=arm64
-    dockerfile: cmd/tempo-cli/Dockerfile
-    password:
-      from_secret: docker_password
-    platform: linux/arm64
-    repo: grafana/tempo-cli
-    username:
-      from_secret: docker_username
-trigger:
-  ref:
-  - refs/heads/main
-  - refs/tags/v*
-  - refs/heads/r?
-  - refs/heads/r??
-  - refs/heads/r???
----
-depends_on:
-- docker-amd64
-- docker-arm64
-kind: pipeline
-name: manifest
-platform:
-  arch: amd64
-  os: linux
-steps:
-- commands:
-  - apk --update --no-cache add bash
-  - git fetch origin --tags
-  - echo $(./tools/image-tag) > .tags
-  image: alpine/git:v2.30.2
-  name: image-tag
-- image: plugins/manifest:1.4.0
-  name: manifest-tempo
-  settings:
-    password:
-      from_secret: docker_password
-    spec: .drone/docker-manifest.tmpl
-    target: tempo
-    username:
-      from_secret: docker_username
-- image: plugins/manifest:1.4.0
-  name: manifest-tempo-vulture
-  settings:
-    password:
-      from_secret: docker_password
-    spec: .drone/docker-manifest.tmpl
-    target: tempo-vulture
-    username:
-      from_secret: docker_username
-- image: plugins/manifest:1.4.0
-  name: manifest-tempo-query
-  settings:
-    password:
-      from_secret: docker_password
-    spec: .drone/docker-manifest.tmpl
-    target: tempo-query
-    username:
-      from_secret: docker_username
-- image: plugins/manifest:1.4.0
-  name: manifest-tempo-cli
-  settings:
-    password:
-      from_secret: docker_password
-    spec: .drone/docker-manifest.tmpl
-    target: tempo-cli
-    username:
-      from_secret: docker_username
-trigger:
-  ref:
-  - refs/heads/main
-  - refs/tags/v*
-  - refs/heads/r?
-  - refs/heads/r??
-  - refs/heads/r???
----
-depends_on:
-- manifest
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: cd-to-dev-env
-platform:
-  arch: amd64
-  os: linux
-steps:
-- commands:
-  - apk --update --no-cache add bash
-  - git fetch origin --tags
-  - echo "grafana/tempo:$(./tools/image-tag)" > .tags-for-cd-tempo
-  - echo "grafana/tempo-query:$(./tools/image-tag)" > .tags-for-cd-tempo_query
-  - echo "grafana/tempo-vulture:$(./tools/image-tag)" > .tags-for-cd-tempo_vulture
-  image: alpine/git:v2.30.2
-  name: image-tag-for-cd
-- image: us.gcr.io/kubernetes-dev/drone/plugins/updater
-  name: update-dev-images
-  settings:
-    config_json: |-
-      {
-        "destination_branch": "master",
-        "pull_request_branch_prefix": "auto-merge/cd-tempo-dev",
-        "pull_request_enabled": true,
-        "pull_request_existing_strategy": "ignore",
-        "repo_name": "deployment_tools",
-        "update_jsonnet_attribute_configs": [
-          {
-            "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
-            "jsonnet_key": "tempo",
-            "jsonnet_value_file": ".tags-for-cd-tempo"
-          },
-          {
-            "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
-            "jsonnet_key": "tempo_query",
-            "jsonnet_value_file": ".tags-for-cd-tempo_query"
-          },
-          {
-            "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
-            "jsonnet_key": "tempo_vulture",
-            "jsonnet_value_file": ".tags-for-cd-tempo_vulture"
-          }
-        ]
-      }
-    github_app_id:
-      from_secret: tempo_app_id_secret
-    github_app_installation_id:
-      from_secret: tempo_app_installation_id_secret
-    github_app_private_key:
-      from_secret: tempo_app_private_key_secret
-trigger:
-  ref:
-  - refs/heads/main
----
-depends_on: []
 image_pull_secrets:
 - dockerconfigjson
 kind: pipeline
@@ -440,6 +171,6 @@ kind: secret
 name: gpg_passphrase
 ---
 kind: signature
-hmac: 549009bef21fd03b82e361c40ad6928b584e18ff762f0890f9302802b124c8b0
+hmac: 829444ce9d30e58a656ca6369a79ecdb01aa76e56c2562c77eb734bf15677eda
 
 ...
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 000000000000..fb5170c5fc7a
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,133 @@
+name: docker-ci-tools
+on:
+  push:
+    branches:
+      - 'main'
+      - 'r[0-9]+'
+    tags:
+      - 'v*'
+
+# Needed to login to DockerHub
+permissions:
+  contents: read
+  id-token: write
+
+jobs:
+
+  get-tag:
+    if: github.repository == 'grafana/tempo'  # skip in forks
+    runs-on: ubuntu-24.04
+    outputs:
+      tag: ${{ steps.get-tag.outputs.tag }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: fetch tags
+        run: git fetch --tags
+
+      - id: get-tag
+        run: |
+          echo "tag=$(./tools/image-tag)" >> "$GITHUB_OUTPUT"
+
+  docker:
+    if: github.repository == 'grafana/tempo'
+    needs: get-tag
+    strategy:
+      matrix:
+        component: [ tempo, tempo-vulture, tempo-query, tempo-cli ]
+        runner_arch: [ { runner: ubuntu-24.04, arch: amd64 }, { runner: github-hosted-ubuntu-arm64, arch: arm64 } ]
+    runs-on: ${{ matrix.runner_arch.runner }}
+    env:
+      TAG: ${{ needs.get-tag.outputs.tag }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: fetch tags
+        run: git fetch --tags
+
+      - name: build-tempo-binaries
+        run: |
+          COMPONENT=${{ matrix.component }} GOARCH=${{ matrix.runner_arch.arch }} make exe
+
+      - name: docker-build
+        run: |
+          TAG_ARCH="$TAG-${{ matrix.runner_arch.arch }}"
+          docker build -f cmd/${{ matrix.component }}/Dockerfile -t grafana/${{ matrix.component }}:$TAG_ARCH .
+
+      - name: Login to DockerHub
+        uses: grafana/shared-workflows/actions/dockerhub-login@dockerhub-login-v1.0.0
+
+      - name: docker-push
+        run: |
+            docker push grafana/${{ matrix.component }}:$TAG_ARCH
+
+
+  cd-to-dev-env:
+    # This job deploys the latest main commit to the dev environment
+    runs-on: ubuntu-24.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: fetch tags
+        run: git fetch --tags
+
+      - name: get-tag
+        run: |
+          echo "grafana/tempo:$(./tools/image-tag)" > .tags-for-cd-tempo
+          echo "grafana/tempo-query:$(./tools/image-tag)" > .tags-for-cd-tempo_query
+          echo "grafana/tempo-vulture:$(./tools/image-tag)" > .tags-for-cd-tempo_vulture
+
+      - name: Authenticate to GAR
+        uses: grafana/shared-workflows/actions/login-to-gar@main
+        id: login-to-gar
+        with:
+          registry: us-docker.pkg.dev
+          environment: prod
+
+      - name: Get Vault secrets
+        uses: grafana/shared-workflows/actions/get-vault-secrets@main
+        with:
+          common_secrets: |
+            GITHUB_APP_ID=updater-app:app-id
+            GITHUB_APP_INSTALLATION_ID=updater-app:app-installation-id
+            GITHUB_APP_PRIVATE_KEY=updater-app:private-key
+
+      - name: Update jsonnet
+        run: |
+          set -e -o pipefail
+
+          cat << EOF > config.json
+          {
+            "destination_branch": "master",
+            "pull_request_branch_prefix": "auto-merge/cd-tempo-dev",
+            "pull_request_enabled": true,
+            "pull_request_existing_strategy": "ignore",
+            "repo_name": "deployment_tools",
+            "update_jsonnet_attribute_configs": [
+              {
+                "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
+                "jsonnet_key": "tempo",
+                "jsonnet_value_file": ".tags-for-cd-tempo"
+              },
+              {
+                "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
+                "jsonnet_key": "tempo_query",
+                "jsonnet_value_file": ".tags-for-cd-tempo_query"
+              },
+              {
+                "file_path": "ksonnet/environments/tempo/dev-us-central-0.tempo-dev-01/images.libsonnet",
+                "jsonnet_key": "tempo_vulture",
+                "jsonnet_value_file": ".tags-for-cd-tempo_vulture"
+              }
+            ]
+          }
+          EOF
+
+          docker run --rm \
+          -e GITHUB_APP_ID="$GITHUB_APP_ID" \
+          -e GITHUB_APP_INSTALLATION_ID="$GITHUB_APP_INSTALLATION_ID" \
+          -e GITHUB_APP_PRIVATE_KEY="$GITHUB_APP_PRIVATE_KEY" \
+          -e CONFIG_JSON="$(cat config.json)" us-docker.pkg.dev/grafanalabs-global/docker-deployment-tools-prod/updater