github.com/grafana/synthetic-monitoring-agent@v0.64.2/.github/workflows/build_and_publish.yaml (about) 1 on: 2 workflow_call: 3 inputs: 4 mode: 5 description: 'The mode to run the workflow in.' 6 required: true 7 type: string 8 9 permissions: 10 packages: none 11 12 jobs: 13 preflight: 14 name: Preflight checks 15 runs-on: ubuntu-latest 16 permissions: 17 contents: read 18 id-token: none 19 outputs: 20 repo_name: ${{ steps.info.outputs.repo_name }} 21 steps: 22 - name: Validate mode 23 env: 24 WF_MODE: ${{ inputs.mode }} 25 run: | 26 if [ "${WF_MODE}" != "dev" ] && [ "${WF_MODE}" != "prod" ]; then 27 echo "Invalid mode: ${WF_MODE}" 28 exit 1 29 fi 30 31 - name: Get repository name 32 id: info 33 env: 34 REPOSITORY: ${{ github.repository }} 35 run: echo "repo_name=${REPOSITORY#*/}" >> "$GITHUB_OUTPUT" 36 37 validate: 38 name: validate 39 needs: [preflight] 40 if: ${{ always() && needs.preflight.result == 'success' }} 41 strategy: 42 matrix: 43 runner: 44 - ubuntu-x64-large 45 - ubuntu-arm64 46 runs-on: ${{ matrix.runner }} 47 permissions: 48 contents: write # needed to upload build artifacts 49 id-token: none 50 services: 51 docker: 52 image: docker:dind@sha256:12e683a161823b2a839aeea999b9d960e6e1f9a97b1679ad6b441982e2d9cf07 53 options: --privileged --shm-size=2g 54 volumes: 55 - /var/run/docker.sock:/var/run/docker.sock:ro 56 57 container: 58 image: ghcr.io/grafana/grafana-build-tools:v1.47.0@sha256:a80098070f2bb1b3c8b74160803c97955c66038a925e8814b91ebbe63f1fd36c 59 volumes: 60 # This works as long as we are using self-hosted runners. 61 # 62 # Self-hosted runners have this file which is used to configure 63 # buildkitd. The file is injected when the image is created. 64 - /etc/buildkitd.toml:/etc/buildkitd.toml 65 outputs: 66 version: ${{ steps.version.outputs.value }} 67 version_bare: ${{ steps.version.outputs.bare_value }} 68 69 steps: 70 - name: build info 71 id: build-info 72 run: | 73 echo "arch=$(go env GOARCH)" >> "$GITHUB_OUTPUT" 74 echo "os=$(go env GOOS)" >> "$GITHUB_OUTPUT" 75 76 - name: checkout 77 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 78 with: 79 persist-credentials: false 80 fetch-depth: 0 81 fetch-tags: true 82 83 - name: Set up global git config 84 run: | 85 # The directory where the code has been checked out ends up belonging 86 # to a different user, so git complains about permissions. Indicate 87 # that it's safe to ignore. 88 git config --global --add safe.directory '*' 89 90 - name: Restore Go cache 91 id: restore-go-cache 92 uses: ./.github/actions/go-cache-restore 93 94 - name: ensure dependencies are up-to-date 95 run: | 96 make deps 97 scripts/enforce-clean 98 99 - name: version 100 id: version 101 run: | 102 make version 103 echo "value=$(cat dist/version)" >> "$GITHUB_OUTPUT" 104 echo "bare_value=$(cat dist/version | cut -d- -f1)" >> "$GITHUB_OUTPUT" 105 106 - name: build 107 run: make build-native 108 109 - name: Download sm-k6 110 run: make sm-k6-native 111 112 - name: lint 113 run: make lint 114 115 - name: test 116 run: make test 117 118 - name: build packages 119 run: make package-native 120 121 - name: Set up Docker Buildx 122 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 123 124 - name: build docker image (no browser) 125 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 126 with: 127 context: . 128 push: false 129 file: Dockerfile.build 130 target: release 131 outputs: type=tar,dest=dist/container-image.no-browser.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar 132 # cache-from: type=gha 133 # cache-to: type=gha,mode=max 134 cache-from: type=local,src=${{ runner.temp }}/.buildx-cache 135 cache-to: type=local,dest=${{ runner.temp }}/.buildx-cache,mode=min 136 137 - name: build docker image (browser) 138 uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 139 with: 140 context: . 141 push: false 142 file: Dockerfile.build 143 target: with-browser 144 outputs: type=tar,dest=dist/container-image.browser.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar 145 # cache-from: type=gha 146 # cache-to: type=gha,mode=max 147 cache-from: type=local,src=${{ runner.temp }}/.buildx-cache 148 cache-to: type=local,dest=${{ runner.temp }}/.buildx-cache,mode=min 149 150 - name: create build artfact 151 env: 152 TARGET_OS: ${{ steps.build-info.outputs.os }} 153 TARGET_ARCH: ${{ steps.build-info.outputs.arch }} 154 run: | 155 tar cf "dist/build-artifacts.${TARGET_OS}-${TARGET_ARCH}.tar" \ 156 dist/container-image.*.*.tar \ 157 "dist/${TARGET_OS}-${TARGET_ARCH}" 158 159 - name: upload build artifact 160 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 161 with: 162 name: build-artifacts-${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }} 163 path: dist/build-artifacts.${{ steps.build-info.outputs.os }}-${{ steps.build-info.outputs.arch }}.tar 164 retention-days: 1 165 if-no-files-found: error 166 overwrite: false 167 168 - name: Save Go cache 169 id: save-go-cache 170 uses: ./.github/actions/go-cache-save 171 with: 172 key: ${{ steps.restore-go-cache.outputs.key }} 173 path: ${{ steps.restore-go-cache.outputs.path }} 174 175 publish_images: 176 name: publish images 177 needs: 178 - preflight 179 - validate 180 if: ${{ always() && needs.validate.result == 'success' && needs.preflight.result == 'success' }} 181 runs-on: ubuntu-x64 182 permissions: 183 contents: read 184 id-token: write # Needed for push-to-gar 185 outputs: 186 image_name: ${{ steps.extract-image-metadata.outputs.image }} 187 image_tag: ${{ steps.extract-image-metadata.outputs.tag }} 188 steps: 189 - name: Get GitHub App token 190 id: get-release-app-token 191 uses: grafana/shared-workflows/actions/create-github-app-token@46f48da11e78ebdba7a8747ae456b11062fac83e # create-github-app-token/v0.3.1 192 with: 193 github_app: sm-release-app 194 195 - name: checkout 196 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 197 with: 198 persist-credentials: false 199 fetch-depth: 0 200 201 - name: Set up global git config 202 run: | 203 # The directory where the code has been checked out ends up belonging 204 # to a different user, so git complains about permissions. Indicate 205 # that it's safe to ignore. 206 git config --global --add safe.directory '*' 207 208 - name: download build artifacts 209 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 210 with: 211 path: dist 212 pattern: build-artifacts-* 213 214 - name: extract build artifacts 215 id: extract-build-artifacts 216 # Note that the download-artifact action will create a directory for 217 # each artifact that it downloads, named afer the artifact's name. 218 # That's the `build-artifacts-*` portion of the path. 219 # 220 # After extracting all the artifacts, this builds an output named 221 # `platforms` that lists all the platforms that are available. This is 222 # used by the step that builds the docker images to tell it what 223 # platforms should be included. 224 run: | 225 find dist/build-artifacts-*/build-artifacts.*.tar -print0 | 226 xargs -r0 -I{} tar -xvpf {} 227 228 { 229 echo 'platforms<<EOT' 230 find dist/ -maxdepth 1 -name 'container-image.*.*.tar' -print0 | 231 xargs -r0 -n1 basename | 232 cut -d. -f3 | 233 tr - / 234 echo 'EOT' 235 } >> "$GITHUB_OUTPUT" 236 237 - name: push container images to GAR (no browser) 238 id: push-to-gar 239 uses: grafana/shared-workflows/actions/docker-build-push-image@ef27c620a88acc9f3007f30be5e9407324e8975b # docker-build-push-image/v0.3.0 240 with: 241 registries: gar 242 gar-environment: ${{ inputs.mode }} 243 gar-image: ${{ needs.preflight.outputs.repo_name }} 244 push: true 245 platforms: ${{ steps.extract-build-artifacts.outputs.platforms }} 246 tags: |- 247 type=raw,value=${{ needs.validate.outputs.version }} 248 type=raw,value=${{ needs.validate.outputs.version_bare }} 249 type=sha,prefix=sha-,format=short 250 latest 251 file: Dockerfile.no-browser 252 253 # There's no need to push browser image to GAR, as this is not used in our infra. 254 255 - name: extract image metadata 256 id: extract-image-metadata 257 run: | 258 # Note that the variable DOCKER_METADATA_OUTPUT_BAKE_FILE_TAGS 259 # already contains the name of the variables. It has the form 260 # key=value\nkey=value\n... 261 ./scripts/extract-image-info "${DOCKER_METADATA_OUTPUT_BAKE_FILE_TAGS}" 262 ./scripts/extract-image-info "${DOCKER_METADATA_OUTPUT_BAKE_FILE_TAGS}" >> "$GITHUB_OUTPUT" 263 264 # Add packages to release, but only in production mode, because dev mode doesn't have a tag. 265 - name: add packages to release 266 id: add-packages-to-release 267 env: 268 GH_TOKEN: ${{ steps.get-release-app-token.outputs.token }} 269 if: ${{ always() && inputs.mode == 'prod' }} 270 run: | 271 tag=${GITHUB_REF##*/} 272 # Make sure this is a tag. The following command will fail otherwise. 273 git rev-parse "refs/tags/$tag" 274 find dist/ -mindepth 2 -maxdepth 2 -type f \( -name \*.rpm -o -name \*.deb -o -name \*.tar.gz \) -print0 | 275 xargs -r0 gh release upload "$tag" 276 277 - name: push container images to docker hub via mirror (no browser) 278 id: push-no-browser-to-docker-hub 279 uses: grafana/shared-workflows/actions/docker-build-push-image@ef27c620a88acc9f3007f30be5e9407324e8975b # docker-build-push-image/v0.3.0 280 with: 281 registries: gar 282 gar-environment: prod 283 gar-repository: dockerhub-${{ needs.preflight.outputs.repo_name }}-prod-mirror 284 gar-image: ${{ needs.preflight.outputs.repo_name }} 285 # Go thru the motions, but publish only in prod mode. 286 push: ${{ inputs.mode == 'prod' }} 287 platforms: ${{ steps.extract-build-artifacts.outputs.platforms }} 288 tags: |- 289 type=raw,value=${{ needs.validate.outputs.version }} 290 type=raw,value=${{ needs.validate.outputs.version_bare }} 291 type=sha,prefix=sha-,format=short 292 latest 293 file: Dockerfile.no-browser 294 295 - name: push container images to docker hub via mirror (browser) 296 id: push-browser-to-docker-hub 297 uses: grafana/shared-workflows/actions/docker-build-push-image@ef27c620a88acc9f3007f30be5e9407324e8975b # docker-build-push-image/v0.3.0 298 with: 299 registries: gar 300 gar-environment: prod 301 gar-repository: dockerhub-${{ needs.preflight.outputs.repo_name }}-prod-mirror 302 gar-image: ${{ needs.preflight.outputs.repo_name }} 303 # Go thru the motions, but publish only in prod mode. 304 push: ${{ inputs.mode == 'prod' }} 305 platforms: ${{ steps.extract-build-artifacts.outputs.platforms }} 306 tags: |- 307 type=raw,value=${{ needs.validate.outputs.version }}-browser 308 type=raw,value=${{ needs.validate.outputs.version_bare }}-browser 309 type=sha,prefix=sha-,suffix=-browser,format=short 310 latest-browser 311 file: Dockerfile.browser 312 313 deploy: 314 name: deploy 315 needs: 316 - preflight 317 - validate 318 - publish_images 319 if: ${{ always() && needs.publish_images.result == 'success' && needs.validate.result == 'success' && needs.preflight.result == 'success' }} 320 runs-on: github-hosted-ubuntu-x64-small 321 permissions: 322 contents: read 323 id-token: write 324 steps: 325 # The following two steps are needed because trigger-argo-workflow is 326 # calling setup-go *after* setup-argo, and setup-argo actually needs go 327 # to obtain GOOS and GOARCH (because it's downloading a remote tarball 328 # where those values are part of the filename). 329 - name: checkout 330 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 331 with: 332 persist-credentials: false 333 fetch-depth: 0 334 335 - name: Setup Go 336 uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 337 with: 338 go-version-file: ./go.mod 339 340 - name: Trigger argo workflow 341 # trigger-argo-workflow hasn't been released yet, so we're using a 342 # commit hash to reference it that has no associated version. 343 uses: grafana/shared-workflows/actions/trigger-argo-workflow@d84db42bd50249775496f814bd875a476849028e 344 with: 345 namespace: synthetic-monitoring-cd 346 workflow_template: deploy-${{ needs.preflight.outputs.repo_name }} 347 extra_args: "--generate-name deploy-${{ needs.preflight.outputs.repo_name }}-" 348 # 'image_version' is the actual version number that is embedded in 349 # the binary and is reported as part of info metrics, so it cannot be 350 # `image_tag` because that might be a diferent value. 351 parameters: | 352 mode=${{ (inputs.mode == 'prod' && 'release') || (inputs.mode == 'dev' && 'dev') }} 353 image=${{ needs.publish_images.outputs.image_name }}:${{ needs.publish_images.outputs.image_tag }} 354 image_name=${{ needs.publish_images.outputs.image_name }} 355 image_version=${{ needs.validate.outputs.version }} 356 dockertag=${{ needs.publish_images.outputs.image_tag }} 357 commit=${{ github.sha }} 358 commit_author=${{ github.actor }} 359 commit_link=${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}