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 }}