name: Build and release core plugins on: workflow_dispatch: inputs: plugin_id: description: "ID of the plugin you want to publish" required: true type: choice options: - grafana-azure-monitor-datasource - grafana-pyroscope-datasource - grafana-testdata-datasource - jaeger - parca - stackdriver - tempo - zipkin concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-${{ inputs.plugin_id }} cancel-in-progress: true env: GRABPL_VERSION: 3.0.44 GCP_BUCKET: integration-artifacts # Dev: plugins-community-staging GCOM_API: https://grafana.com # Dev: https://grafana-dev.com # These permissions are needed to assume roles from Github's OIDC. permissions: contents: read id-token: write jobs: build-and-publish: name: Build and publish ${{ inputs.plugin_id }} runs-on: ubuntu-latest outputs: type: ${{ steps.get_dir.outputs.dir }} has_backend: ${{ steps.check_backend.outputs.has_backend }} version: ${{ steps.build_frontend.outputs.version }} steps: - name: checkout uses: actions/checkout@v4 - name: Verify inputs run: | if [ -z ${{ inputs.plugin_id }} ]; then echo "Missing plugin ID"; exit 1; fi - id: get-secrets uses: grafana/shared-workflows/actions/get-vault-secrets@main with: # Secrets placed in the ci/repo/grafana// path in Vault repo_secrets: | PLUGINS_GOOGLE_CREDENTIALS=core-plugins-build-and-release:PLUGINS_GOOGLE_CREDENTIALS PLUGINS_GRAFANA_API_KEY=core-plugins-build-and-release:PLUGINS_GRAFANA_API_KEY PLUGINS_GCOM_TOKEN=core-plugins-build-and-release:PLUGINS_GCOM_TOKEN - name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v2' with: credentials_json: '${{ env.PLUGINS_GOOGLE_CREDENTIALS }}' - name: 'Set up Cloud SDK' uses: 'google-github-actions/setup-gcloud@v2' - name: Setup nodejs environment uses: actions/setup-node@v4 with: node-version-file: .nvmrc cache: yarn - name: Find plugin directory shell: bash id: get_dir run: | dir=$(dirname \ $(egrep -lir --include=plugin.json --exclude-dir=dist \ '"id": "${{ inputs.plugin_id }}"' \ public/app/plugins \ ) \ ) echo "dir=${dir}" >> $GITHUB_OUTPUT - name: Install frontend dependencies shell: bash working-directory: ${{ steps.get_dir.outputs.dir }} run: | yarn install --immutable - name: Download grabpl executable shell: sh working-directory: ${{ steps.get_dir.outputs.dir }} run: | [ ! -d ./bin ] && mkdir -pv ./bin || true curl -fL -o ./bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v${{ env.GRABPL_VERSION }}/grabpl chmod 0755 ./bin/grabpl - name: Check backend id: check_backend shell: bash run: | if egrep -qr --include=main.go 'datasource.Manage\("${{ inputs.plugin_id }}"' pkg/tsdb; then echo "has_backend=true" >> $GITHUB_OUTPUT else echo "has_backend=false" >> $GITHUB_OUTPUT fi - name: Setup golang environment uses: actions/setup-go@v4 if: steps.check_backend.outputs.has_backend == 'true' with: go-version-file: go.mod - name: Install Mage shell: bash if: steps.check_backend.outputs.has_backend == 'true' run: | go install github.com/magefile/mage - name: Check tools shell: bash working-directory: ${{ steps.get_dir.outputs.dir }} run: | echo "=======================================" echo " Frontend tools" echo "=======================================" echo "-------- node version -----" node --version echo "-------- npm version -----" npm --version echo "-------- yarn version -----" yarn --version echo "=======================================" echo " Misc tools" echo "=======================================" echo "-------- docker version -----" docker --version echo "-------- jq version -----" jq --version echo "-------- grabpl version -----" ./bin/grabpl --version echo "=======================================" - name: Check backend tools shell: bash if: steps.check_backend.outputs.has_backend == 'true' working-directory: ${{ steps.get_dir.outputs.dir }} run: | echo "=======================================" echo " Backend tools" echo "=======================================" echo "-------- go version -----" go version echo "-------- mage version -----" mage --version echo "=======================================" - name: build:frontend shell: bash id: build_frontend run: | command="plugin:build:commit" if [ "$GITHUB_REF" != "refs/heads/main" ]; then # Release branch, do not add commit hash to version command="plugin:build" fi yarn $command --scope="@grafana-plugins/${{ inputs.plugin_id }}" version=$(cat ${{ steps.get_dir.outputs.dir }}/dist/plugin.json | jq -r .info.version) echo "version=${version}" >> $GITHUB_OUTPUT - name: build:backend if: steps.check_backend.outputs.has_backend == 'true' shell: bash env: VERSION: ${{ steps.build_frontend.outputs.version }} run: | make build-plugin-go PLUGIN_ID=${{ inputs.plugin_id }} - name: package working-directory: ${{ steps.get_dir.outputs.dir }} run: | mkdir -p ci/jobs/package bin/grabpl plugin package env: GRAFANA_API_KEY: ${{ env.PLUGINS_GRAFANA_API_KEY }} PLUGIN_SIGNATURE_TYPE: grafana - name: Check existing release env: GCOM_TOKEN: ${{ env.PLUGINS_GCOM_TOKEN }} VERSION: ${{ steps.build_frontend.outputs.version }} run: | api_res=$(curl -X 'GET' -H "Authorization: Bearer $GCOM_TOKEN" \ '${{ env.GCOM_API}}/api/plugins/${{ inputs.plugin_id }}?version=$VERSION' \ -H 'accept: application/json') api_res_code=$(echo $api_res | jq -r .code) if [ "$api_res_code" = "NotFound" ]; then echo "No existing release found" else echo "Expecting a missing release, got:" echo $api_res exit 1 fi - name: store build artifacts uses: actions/upload-artifact@v4 with: name: build-artifacts path: ${{ steps.get_dir.outputs.dir }}/ci/packages/*.zip - name: Publish release to Google Cloud Storage working-directory: ${{ steps.get_dir.outputs.dir }} env: VERSION: ${{ steps.build_frontend.outputs.version }} run: | echo "Publish release to Google Cloud Storage:" touch ci/packages/windows ci/packages/darwin ci/packages/linux ci/packages/any gsutil -m cp -r ci/packages/*windows* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/windows gsutil -m cp -r ci/packages/*linux* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux gsutil -m cp -r ci/packages/*darwin* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin gsutil -m cp -r ci/packages/*any* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/any - name: Publish new plugin version on grafana.com if: steps.check_backend.outputs.has_backend == 'true' working-directory: ${{ steps.get_dir.outputs.dir }} env: GCOM_TOKEN: ${{ env.PLUGINS_GCOM_TOKEN }} VERSION: ${{ steps.build_frontend.outputs.version }} run: | echo "Publish new plugin version on grafana.com:" echo "Plugin version: ${VERSION}" result=`curl -H "Authorization: Bearer $GCOM_TOKEN" -H "Content-Type: application/json" ${{ env.GCOM_API}}/api/plugins -d "{ \"url\": \"https://github.com/grafana/grafana/tree/main/${{ steps.get_dir.outputs.dir }}\", \"download\": { \"linux-amd64\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_amd64.zip\", \"md5\": \"$(cat ci/packages/info-linux_amd64.json | jq -r .plugin.md5)\" }, \"linux-arm64\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_arm64.zip\", \"md5\": \"$(cat ci/packages/info-linux_arm64.json | jq -r .plugin.md5)\" }, \"linux-arm\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_arm.zip\", \"md5\": \"$(cat ci/packages/info-linux_arm.json | jq -r .plugin.md5)\" }, \"windows-amd64\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/windows/${{ inputs.plugin_id }}-${VERSION}.windows_amd64.zip\", \"md5\": \"$(cat ci/packages/info-windows_amd64.json | jq -r .plugin.md5)\" }, \"darwin-amd64\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin/${{ inputs.plugin_id }}-${VERSION}.darwin_amd64.zip\", \"md5\": \"$(cat ci/packages/info-darwin_amd64.json | jq -r .plugin.md5)\" }, \"darwin-arm64\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin/${{ inputs.plugin_id }}-${VERSION}.darwin_arm64.zip\", \"md5\": \"$(cat ci/packages/info-darwin_arm64.json | jq -r .plugin.md5)\" } } }"` if [[ "$(echo $result | jq -r .version)" == "null" ]]; then echo "Failed to publish plugin version. Got:" echo $result exit 1 fi - name: Publish new plugin version on grafana.com (frontend only) if: steps.check_backend.outputs.has_backend == 'false' working-directory: ${{ steps.get_dir.outputs.dir }} env: GCOM_TOKEN: ${{ env.PLUGINS_GCOM_TOKEN }} VERSION: ${{ steps.build_frontend.outputs.version }} run: | echo "Publish new plugin version on grafana.com:" echo "Plugin version: ${VERSION}" result=`curl -H "Authorization: Bearer $GCOM_TOKEN" -H "Content-Type: application/json" ${{ env.GCOM_API}}/api/plugins -d "{ \"url\": \"https://github.com/grafana/grafana/tree/main/${{ steps.get_dir.outputs.dir }}\", \"download\": { \"any\": { \"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/any/${{ inputs.plugin_id }}-${VERSION}.any.zip\", \"md5\": \"$(cat ci/packages/info-any.json | jq -r .plugin.md5)\" } } }"` if [[ "$(echo $result | jq -r .version)" == "null" ]]; then echo "Failed to publish plugin version. Got:" echo $result exit 1 fi