mirror of https://github.com/grafana/grafana.git
				
				
				
			Chore: Simplify Levitate breaking changes workflow (#80014)
* Test using an app instead of token for this workflow * Rename workflow for testing * Add a test workflow * Test 1 * Integrate report * Checkout repository * Try with github token instad of the app * Use short slog instead of adding org * Add failure to pipeline when breakikng * Change exit code to report * Improve message * Restore files * Temporarily lift restriction * Put pack path restriction * remove comment
This commit is contained in:
		
							parent
							
								
									91e49ec0d6
								
							
						
					
					
						commit
						fc8e2472e1
					
				|  | @ -1,34 +0,0 @@ | |||
| # Workflow for skipping the Levitate detection | ||||
| # (This is needed because workflows that are skipped due to path filtering will show up as pending in Github. | ||||
| # As this has the same name as the one in detect-breaking-changes-build.yml it will take over in these cases and succeed quickly.) | ||||
| 
 | ||||
| name: Levitate / Detect breaking changes | ||||
| 
 | ||||
| on: | ||||
|   pull_request: | ||||
|     paths-ignore: | ||||
|       - "packages/**" | ||||
|     branches: | ||||
|       - 'main' | ||||
| 
 | ||||
| jobs: | ||||
|   detect: | ||||
|     name: Detect breaking changes | ||||
|     runs-on: ubuntu-latest | ||||
| 
 | ||||
|     steps: | ||||
|       - name: Skipping | ||||
|         run: echo "No modifications in the public API (packages/), skipping." | ||||
| 
 | ||||
|         # Build and persist output as a JSON (we need to tell the report workflow that the check has been skipped) | ||||
|       - name: Persisting the check output | ||||
|         run: | | ||||
|           mkdir -p ./levitate | ||||
|           echo "{ \"shouldSkip\": true }" > ./levitate/result.json | ||||
| 
 | ||||
|       # Upload artifact (so it can be used in the more privileged "report" workflow) | ||||
|       - name: Upload check output as artifact | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: levitate | ||||
|           path: levitate/ | ||||
|  | @ -1,163 +0,0 @@ | |||
| # Only runs if anything under the packages/ directory changes. | ||||
| # (Otherwise detect-breaking-changes-build-skip.yml takes over) | ||||
| 
 | ||||
| name: Levitate / Detect breaking changes | ||||
| 
 | ||||
| on: | ||||
|   pull_request: | ||||
|     paths: | ||||
|       - 'packages/**' | ||||
|     branches: | ||||
|       - 'main' | ||||
| 
 | ||||
| jobs: | ||||
|   buildPR: | ||||
|     name: Build PR | ||||
|     runs-on: ubuntu-latest | ||||
|     defaults: | ||||
|       run: | ||||
|         working-directory: './pr' | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
|       with: | ||||
|         path: './pr' | ||||
|     - uses: actions/setup-node@v4 | ||||
|       with: | ||||
|         node-version: 20.9.0 | ||||
| 
 | ||||
|     - name: Get yarn cache directory path | ||||
|       id: yarn-cache-dir-path | ||||
|       run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | ||||
| 
 | ||||
|     - name: Restore yarn cache | ||||
|       uses: actions/cache@v3.3.1 | ||||
|       id: yarn-cache | ||||
|       with: | ||||
|         path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
|         key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }} | ||||
|         restore-keys: | | ||||
|           yarn-cache-folder- | ||||
| 
 | ||||
|     - name: Install dependencies | ||||
|       run: yarn install --immutable | ||||
| 
 | ||||
|     - name: Build packages | ||||
|       run: yarn packages:build | ||||
| 
 | ||||
|     - name: Pack packages | ||||
|       run: yarn packages:pack --out ./%s.tgz | ||||
| 
 | ||||
|     - name: Zip built tarballed packages | ||||
|       run: zip -r ./pr_built_packages.zip ./packages/**/*.tgz | ||||
| 
 | ||||
|     - name: Upload build output as artifact | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: buildPr | ||||
|         path: './pr/pr_built_packages.zip' | ||||
| 
 | ||||
|   buildBase: | ||||
|     name: Build Base | ||||
|     runs-on: ubuntu-latest | ||||
|     defaults: | ||||
|       run: | ||||
|         working-directory: './base' | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
|       with: | ||||
|         path: './base' | ||||
|         ref: ${{ github.event.pull_request.base.ref }} | ||||
| 
 | ||||
|     - uses: actions/setup-node@v4 | ||||
|       with: | ||||
|         node-version: 20.9.0 | ||||
| 
 | ||||
|     - name: Get yarn cache directory path | ||||
|       id: yarn-cache-dir-path | ||||
|       run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | ||||
| 
 | ||||
|     - name: Restore yarn cache | ||||
|       uses: actions/cache@v3.3.1 | ||||
|       id: yarn-cache | ||||
|       with: | ||||
|         path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
|         key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }} | ||||
|         restore-keys: | | ||||
|           yarn-cache-folder- | ||||
| 
 | ||||
|     - name: Install dependencies | ||||
|       run: yarn install --immutable | ||||
| 
 | ||||
|     - name: Build packages | ||||
|       run: yarn packages:build | ||||
| 
 | ||||
|     - name: Pack packages | ||||
|       run: yarn packages:pack --out ./%s.tgz | ||||
| 
 | ||||
|     - name: Zip built tarballed packages | ||||
|       run: zip -r ./base_built_packages.zip ./packages/**/*.tgz | ||||
| 
 | ||||
|     - name: Upload build output as artifact | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: buildBase | ||||
|         path: './base/base_built_packages.zip' | ||||
| 
 | ||||
|   Detect: | ||||
|     name: Detect breaking changes | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: ['buildPR', 'buildBase'] | ||||
|     env: | ||||
|       GITHUB_STEP_NUMBER: 8 | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Get built packages from pr | ||||
|         uses: actions/download-artifact@v3 | ||||
|         with: | ||||
|           name: buildPr | ||||
| 
 | ||||
|       - name: Get built packages from base | ||||
|         uses: actions/download-artifact@v3 | ||||
|         with: | ||||
|           name: buildBase | ||||
| 
 | ||||
|       - name: Unzip artifact from pr | ||||
|         run: unzip -j pr_built_packages.zip -d ./pr && rm pr_built_packages.zip | ||||
| 
 | ||||
|       - name: Unzip artifact from base | ||||
|         run: unzip -j base_built_packages.zip -d ./base && rm base_built_packages.zip | ||||
| 
 | ||||
|       - name: Get link for the Github Action job | ||||
|         id: job | ||||
|         uses: actions/github-script@v6 | ||||
|         with: | ||||
|           script: | | ||||
|               const name = 'Detect breaking changes'; | ||||
|               const script = require('./.github/workflows/scripts/pr-get-job-link.js') | ||||
|               await script({name, github, context, core}) | ||||
| 
 | ||||
|       - name: Detect breaking changes | ||||
|         id: breaking-changes | ||||
|         run: ./scripts/check-breaking-changes.sh | ||||
|         env: | ||||
|           FORCE_COLOR: 3 | ||||
|           GITHUB_JOB_LINK: ${{ steps.job.outputs.link }} | ||||
| 
 | ||||
|       - name: Persisting the check output | ||||
|         run: | | ||||
|             mkdir -p ./levitate | ||||
|             echo "{ \"exit_code\": ${{ steps.breaking-changes.outputs.is_breaking }}, \"message\": \"${{ steps.breaking-changes.outputs.message }}\", \"job_link\": \"${{ steps.job.outputs.link }}#step:${GITHUB_STEP_NUMBER}:1\", \"pr_number\": \"${{ github.event.pull_request.number }}\" }" > ./levitate/result.json | ||||
| 
 | ||||
|       - name: Upload check output as artifact | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: levitate | ||||
|           path: levitate/ | ||||
| 
 | ||||
|       - name: Exit | ||||
|         run: exit ${{ steps.breaking-changes.outputs.is_breaking }} | ||||
|         shell: bash | ||||
|  | @ -0,0 +1,337 @@ | |||
| # Only runs if anything under the packages/ directory changes. | ||||
| 
 | ||||
| name: Levitate / Detect breaking changes in PR | ||||
| 
 | ||||
| on: | ||||
|   pull_request: | ||||
|     paths: | ||||
|       - 'packages/**' | ||||
|     branches: | ||||
|       - 'main' | ||||
| 
 | ||||
| jobs: | ||||
|   buildPR: | ||||
|     name: Build PR | ||||
|     runs-on: ubuntu-latest | ||||
|     defaults: | ||||
|       run: | ||||
|         working-directory: './pr' | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
|       with: | ||||
|         path: './pr' | ||||
|     - uses: actions/setup-node@v4 | ||||
|       with: | ||||
|         node-version: 20.9.0 | ||||
| 
 | ||||
| 
 | ||||
|     - name: Get yarn cache directory path | ||||
|       id: yarn-cache-dir-path | ||||
|       run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | ||||
| 
 | ||||
|     - name: Restore yarn cache | ||||
|       uses: actions/cache@v3.3.1 | ||||
|       id: yarn-cache | ||||
|       with: | ||||
|         path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
|         key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }} | ||||
|         restore-keys: | | ||||
|           yarn-cache-folder- | ||||
| 
 | ||||
|     - name: Install dependencies | ||||
|       run: yarn install --immutable | ||||
| 
 | ||||
|     - name: Build packages | ||||
|       run: yarn packages:build | ||||
| 
 | ||||
|     - name: Pack packages | ||||
|       run: yarn packages:pack --out ./%s.tgz | ||||
| 
 | ||||
|     - name: Zip built tarballed packages | ||||
|       run: zip -r ./pr_built_packages.zip ./packages/**/*.tgz | ||||
| 
 | ||||
|     - name: Upload build output as artifact | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: buildPr | ||||
|         path: './pr/pr_built_packages.zip' | ||||
| 
 | ||||
|   buildBase: | ||||
|     name: Build Base | ||||
|     runs-on: ubuntu-latest | ||||
|     defaults: | ||||
|       run: | ||||
|         working-directory: './base' | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
|       with: | ||||
|         path: './base' | ||||
|         ref: ${{ github.event.pull_request.base.ref }} | ||||
| 
 | ||||
|     - uses: actions/setup-node@v4 | ||||
|       with: | ||||
|         node-version: 20.9.0 | ||||
| 
 | ||||
|     - name: Get yarn cache directory path | ||||
|       id: yarn-cache-dir-path | ||||
|       run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | ||||
| 
 | ||||
|     - name: Restore yarn cache | ||||
|       uses: actions/cache@v3.3.1 | ||||
|       id: yarn-cache | ||||
|       with: | ||||
|         path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
|         key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }} | ||||
|         restore-keys: | | ||||
|           yarn-cache-folder- | ||||
| 
 | ||||
|     - name: Install dependencies | ||||
|       run: yarn install --immutable | ||||
| 
 | ||||
|     - name: Build packages | ||||
|       run: yarn packages:build | ||||
| 
 | ||||
|     - name: Pack packages | ||||
|       run: yarn packages:pack --out ./%s.tgz | ||||
| 
 | ||||
|     - name: Zip built tarballed packages | ||||
|       run: zip -r ./base_built_packages.zip ./packages/**/*.tgz | ||||
| 
 | ||||
|     - name: Upload build output as artifact | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: buildBase | ||||
|         path: './base/base_built_packages.zip' | ||||
| 
 | ||||
|   Detect: | ||||
|     name: Detect breaking changes | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: ['buildPR', 'buildBase'] | ||||
|     env: | ||||
|       GITHUB_STEP_NUMBER: 8 | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Get built packages from pr | ||||
|         uses: actions/download-artifact@v3 | ||||
|         with: | ||||
|           name: buildPr | ||||
| 
 | ||||
|       - name: Get built packages from base | ||||
|         uses: actions/download-artifact@v3 | ||||
|         with: | ||||
|           name: buildBase | ||||
| 
 | ||||
|       - name: Unzip artifact from pr | ||||
|         run: unzip -j pr_built_packages.zip -d ./pr && rm pr_built_packages.zip | ||||
| 
 | ||||
|       - name: Unzip artifact from base | ||||
|         run: unzip -j base_built_packages.zip -d ./base && rm base_built_packages.zip | ||||
| 
 | ||||
|       - name: Get link for the Github Action job | ||||
|         id: job | ||||
|         uses: actions/github-script@v6 | ||||
|         with: | ||||
|           script: | | ||||
|               const name = 'Detect breaking changes'; | ||||
|               const script = require('./.github/workflows/scripts/pr-get-job-link.js') | ||||
|               await script({name, github, context, core}) | ||||
| 
 | ||||
|       - name: Detect breaking changes | ||||
|         id: breaking-changes | ||||
|         run: ./scripts/check-breaking-changes.sh | ||||
|         env: | ||||
|           FORCE_COLOR: 3 | ||||
|           GITHUB_JOB_LINK: ${{ steps.job.outputs.link }} | ||||
| 
 | ||||
|       - name: Persisting the check output | ||||
|         run: | | ||||
|             mkdir -p ./levitate | ||||
|             echo "{ \"exit_code\": ${{ steps.breaking-changes.outputs.is_breaking }}, \"message\": \"${{ steps.breaking-changes.outputs.message }}\", \"job_link\": \"${{ steps.job.outputs.link }}#step:${GITHUB_STEP_NUMBER}:1\", \"pr_number\": \"${{ github.event.pull_request.number }}\" }" > ./levitate/result.json | ||||
| 
 | ||||
|       - name: Upload check output as artifact | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: levitate | ||||
|           path: levitate/ | ||||
| 
 | ||||
| 
 | ||||
|   Report: | ||||
|     name: Report breaking changes in PR | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: ['Detect'] | ||||
| 
 | ||||
|     steps: | ||||
|         - name: "Generate token" | ||||
|           id: generate_token | ||||
|           uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 | ||||
|           with: | ||||
|             app_id: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_ID }} | ||||
|             private_key: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_PEM }} | ||||
| 
 | ||||
|         - uses: actions/checkout@v4 | ||||
| 
 | ||||
|         - name: 'Download artifact' | ||||
|           uses: actions/download-artifact@v3 | ||||
|           with: | ||||
|             name: levitate | ||||
| 
 | ||||
|         - name: Parsing levitate result | ||||
|           uses: actions/github-script@v6 | ||||
|           id: levitate-run | ||||
|           with: | ||||
|             script: | | ||||
|               const filePath = 'result.json'; | ||||
|               const script = require('./.github/workflows/scripts/json-file-to-job-output.js'); | ||||
|               await script({ core, filePath }); | ||||
| 
 | ||||
|         # Check if label exists | ||||
|         - name: Check if "levitate breaking change" label exists | ||||
|           id: does-label-exist | ||||
|           uses: actions/github-script@v6 | ||||
|           env: | ||||
|             PR_NUMBER: ${{ github.event.pull_request.number }} | ||||
|           with: | ||||
|             script: | | ||||
|               const { data } = await github.rest.issues.listLabelsOnIssue({ | ||||
|                 issue_number: process.env.PR_NUMBER, | ||||
|                 owner: context.repo.owner, | ||||
|                 repo: context.repo.repo, | ||||
|               }); | ||||
|               const labels = data.map(({ name }) => name); | ||||
|               const doesExist = labels.includes('levitate breaking change'); | ||||
| 
 | ||||
|               return doesExist ? 1 : 0; | ||||
| 
 | ||||
|         # put the markdown into a variable | ||||
|         - name: Levitate Markdown | ||||
|           id: levitate-markdown | ||||
|           run: | | ||||
|               if [ -f "levitate.md" ]; then | ||||
|               { | ||||
|                 echo 'levitate_markdown<<EOF' | ||||
|                 cat levitate.md | ||||
|                 echo EOF | ||||
|               } >> $GITHUB_OUTPUT | ||||
|               else | ||||
|                 echo "levitate_markdown=No breaking changes detected" >> $GITHUB_OUTPUT | ||||
|               fi | ||||
| 
 | ||||
| 
 | ||||
|         # Comment on the PR | ||||
|         - name: Comment on PR | ||||
|           uses: marocchino/sticky-pull-request-comment@v2 | ||||
|           with: | ||||
|             header: levitate-breaking-change-comment | ||||
|             number: ${{ github.event.pull_request.number }} | ||||
|             message: | | ||||
|               ⚠️   **Possible breaking changes (md version)***    ⚠️ | ||||
| 
 | ||||
|               ${{ steps.levitate-markdown.outputs.levitate_markdown }} | ||||
| 
 | ||||
|               [Read our guideline](https://github.com/grafana/grafana/blob/main/contribute/breaking-changes-guide/breaking-changes-guide.md) | ||||
|               [Console output](${{ steps.levitate-run.outputs.job_link }}) | ||||
|             GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||||
| 
 | ||||
|         # Remove comment from the PR (no more breaking changes) | ||||
|         - name: Remove comment from PR | ||||
|           if: steps.levitate-run.outputs.exit_code == 0 | ||||
|           uses: marocchino/sticky-pull-request-comment@v2 | ||||
|           with: | ||||
|             header: levitate-breaking-change-comment | ||||
|             number: ${{ github.event.pull_request.number }} | ||||
|             delete: true | ||||
|             GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||||
| 
 | ||||
|         # Posts a notification to Slack if a PR has a breaking change and it did not have a breaking change before | ||||
|         - name: Post to Slack | ||||
|           id: slack | ||||
|           if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && env.HAS_SECRETS | ||||
|           uses: slackapi/slack-github-action@v1.24.0 | ||||
|           with: | ||||
|             payload: | | ||||
|               { | ||||
|                 "pr_link": "https://github.com/grafana/grafana/pull/${{ steps.levitate-run.outputs.pr_number }}", | ||||
|                 "pr_number": "${{ steps.levitate-run.outputs.pr_number }}", | ||||
|                 "job_link": "${{ steps.levitate-run.outputs.job_link }}", | ||||
|                 "reporting_job_link": "${{ github.event.workflow_run.html_url }}", | ||||
|                 "message": "${{ steps.levitate-run.outputs.message }}" | ||||
|               } | ||||
|           env: | ||||
|             SLACK_WEBHOOK_URL: ${{ secrets.SLACK_LEVITATE_WEBHOOK_URL }} | ||||
|             HAS_SECRETS: ${{ (github.repository == 'grafana/grafana' || secrets.SLACK_LEVITATE_WEBHOOK_URL != '') || '' }} | ||||
| 
 | ||||
|         # Add the label | ||||
|         - name: Add "levitate breaking change" label | ||||
|           if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 | ||||
|           uses: actions/github-script@v6 | ||||
|           env: | ||||
|             PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|           with: | ||||
|             github-token: ${{ steps.generate_token.outputs.token }} | ||||
|             script: | | ||||
|               await github.rest.issues.addLabels({ | ||||
|                 issue_number: process.env.PR_NUMBER, | ||||
|                 owner: context.repo.owner, | ||||
|                 repo: context.repo.repo, | ||||
|                 labels: ['levitate breaking change'] | ||||
|               }) | ||||
| 
 | ||||
|         # Remove label (no more breaking changes) | ||||
|         - name: Remove "levitate breaking change" label | ||||
|           if: steps.levitate-run.outputs.exit_code == 0 && steps.does-label-exist.outputs.result == 1 | ||||
|           uses: actions/github-script@v6 | ||||
|           env: | ||||
|             PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|           with: | ||||
|             github-token: ${{ steps.generate_token.outputs.token }} | ||||
|             script: | | ||||
|               await github.rest.issues.removeLabel({ | ||||
|                 issue_number: process.env.PR_NUMBER, | ||||
|                 owner: context.repo.owner, | ||||
|                 repo: context.repo.repo, | ||||
|                 name: 'levitate breaking change' | ||||
|               }) | ||||
| 
 | ||||
|         # Add reviewers | ||||
|         # This is very weird, the actual request goes through (comes back with a 201), but does not assign the team. | ||||
|         # Related issue: https://github.com/renovatebot/renovate/issues/1908 | ||||
|         - name: Add "grafana/plugins-platform-frontend" as a reviewer | ||||
|           if: steps.levitate-run.outputs.exit_code | ||||
|           uses: actions/github-script@v6 | ||||
|           env: | ||||
|             PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|           with: | ||||
|             github-token: ${{ steps.generate_token.outputs.token }} | ||||
|             script: | | ||||
|               await github.rest.pulls.requestReviewers({ | ||||
|                 pull_number: process.env.PR_NUMBER, | ||||
|                 owner: context.repo.owner, | ||||
|                 repo: context.repo.repo, | ||||
|                 reviewers: [], | ||||
|                 team_reviewers: ['plugins-platform-frontend'] | ||||
|               }); | ||||
| 
 | ||||
|         # Remove reviewers (no more breaking changes) | ||||
|         - name: Remove "grafana/plugins-platform-frontend" from the list of reviewers | ||||
|           if: steps.levitate-run.outputs.exit_code == 0 | ||||
|           uses: actions/github-script@v6 | ||||
|           env: | ||||
|             PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|           with: | ||||
|             github-token: ${{ steps.generate_token.outputs.token }} | ||||
|             script: | | ||||
|               await github.rest.pulls.removeRequestedReviewers({ | ||||
|                 pull_number: process.env.PR_NUMBER, | ||||
|                 owner: context.repo.owner, | ||||
|                 repo: context.repo.repo, | ||||
|                 reviewers: [], | ||||
|                 team_reviewers: ['plugins-platform-frontend'] | ||||
|               }); | ||||
| 
 | ||||
|         - name: Exit | ||||
|           run: exit ${{ steps.levitate-run.outputs.exit_code }} | ||||
|           shell: bash | ||||
|  | @ -1,223 +0,0 @@ | |||
| name: Levitate / Report breaking changes | ||||
| 
 | ||||
| on: | ||||
|   workflow_run: | ||||
|     workflows: ["Levitate / Detect breaking changes"] | ||||
|     types: [completed] | ||||
| 
 | ||||
| permissions: | ||||
|   pull-requests: write | ||||
| 
 | ||||
| jobs: | ||||
|   notify: | ||||
|     name: Report | ||||
|     runs-on: ubuntu-latest | ||||
|     env: | ||||
|       ARTIFACT_NAME: 'levitate' # The name of the artifact that we would like to download | ||||
|       ARTIFACT_FOLDER: '${{ github.workspace }}/tmp' # The name of the folder where we will download the artifact to | ||||
|     permissions: | ||||
|       contents: read | ||||
|       issues: write | ||||
|       pull-requests: write | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
| 
 | ||||
|     # Download artifact (as a .zip archive) | ||||
|     - name: 'Download artifact' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         RUN_ID: ${{ github.event.workflow_run.id }} | ||||
|       with: | ||||
|         script: | | ||||
|           const fs = require('fs'); | ||||
| 
 | ||||
|           const { owner, repo } = context.repo; | ||||
|           const runId = process.env.RUN_ID; | ||||
|           const artifactName = process.env.ARTIFACT_NAME; | ||||
|           const artifactFolder = process.env.ARTIFACT_FOLDER; | ||||
|           const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ | ||||
|               owner, | ||||
|               repo, | ||||
|               run_id: runId, | ||||
|           }); | ||||
|           const artifact = artifacts.data.artifacts.find(a => a.name === artifactName); | ||||
| 
 | ||||
|           if (!artifact) { | ||||
|               throw new Error(`Could not find artifact ${ artifactName } in workflow (${ runId })`); | ||||
|           } | ||||
| 
 | ||||
|           const download = await github.rest.actions.downloadArtifact({ | ||||
|               owner, | ||||
|               repo, | ||||
|               artifact_id: artifact.id, | ||||
|               archive_format: 'zip', | ||||
|           }); | ||||
| 
 | ||||
|           fs.mkdirSync(artifactFolder, { recursive: true }); | ||||
|           fs.writeFileSync(`${ artifactFolder }/${ artifactName }.zip`, Buffer.from(download.data)); | ||||
| 
 | ||||
|     # Unzip artifact | ||||
|     - name: Unzip artifact | ||||
|       run: unzip "${ARTIFACT_FOLDER}/${ARTIFACT_NAME}.zip" -d "${ARTIFACT_FOLDER}" | ||||
| 
 | ||||
|      # Parse the artifact and register fields as step output variables | ||||
|       # (All fields in the JSON will be available as ${{ steps.levitate-run.outputs.<field-name> }} | ||||
|     - name: Parsing levitate result | ||||
|       uses: actions/github-script@v6 | ||||
|       id: levitate-run | ||||
|       with: | ||||
|         script: | | ||||
|           const filePath = `${ process.env.ARTIFACT_FOLDER }/result.json`; | ||||
|           const script = require('./.github/workflows/scripts/json-file-to-job-output.js'); | ||||
|           await script({ core, filePath }); | ||||
| 
 | ||||
|     # Skip - print a message if the "Detect" workflow was skipped | ||||
|     - name: Check if the workflow should be skipped | ||||
|       if: steps.levitate-run.outputs.shouldSkip == 'true' | ||||
|       run: echo "Skipping." | ||||
| 
 | ||||
|     # Check if label exists | ||||
|     - name: Check if "levitate breaking change" label exists | ||||
|       id: does-label-exist | ||||
|       if: steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} | ||||
|       with: | ||||
|         script: | | ||||
|           const { data } = await github.rest.issues.listLabelsOnIssue({ | ||||
|             issue_number: process.env.PR_NUMBER, | ||||
|             owner: context.repo.owner, | ||||
|             repo: context.repo.repo, | ||||
|           }); | ||||
|           const labels = data.map(({ name }) => name); | ||||
|           const doesExist = labels.includes('levitate breaking change'); | ||||
| 
 | ||||
|           return doesExist ? 1 : 0; | ||||
| 
 | ||||
|     # put the markdown into a variable | ||||
|     - name: Levitate Markdown | ||||
|       id: levitate-markdown | ||||
|       if: steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       run: | | ||||
|           if [ -f "${ARTIFACT_FOLDER}/levitate.md" ]; then | ||||
|           { | ||||
|             echo 'levitate_markdown<<EOF' | ||||
|             cat ${ARTIFACT_FOLDER}/levitate.md | ||||
|             echo EOF | ||||
|           } >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "levitate_markdown=No breaking changes detected" >> $GITHUB_OUTPUT | ||||
|           fi | ||||
| 
 | ||||
| 
 | ||||
|     # Comment on the PR | ||||
|     - name: Comment on PR | ||||
|       if: steps.levitate-run.outputs.exit_code == 1 && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: marocchino/sticky-pull-request-comment@v2 | ||||
|       with: | ||||
|         number: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|         message: | | ||||
|           ⚠️   **Possible breaking changes (md version)** | ||||
| 
 | ||||
|           ${{ steps.levitate-markdown.outputs.levitate_markdown }} | ||||
| 
 | ||||
|           [Console output](${{ steps.levitate-run.outputs.job_link }}) | ||||
|           [Read our guideline](https://github.com/grafana/grafana/blob/main/contribute/breaking-changes-guide/breaking-changes-guide.md) | ||||
| 
 | ||||
|     # Remove comment from the PR (no more breaking changes) | ||||
|     - name: Remove comment from PR | ||||
|       if: steps.levitate-run.outputs.exit_code == 0 && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: marocchino/sticky-pull-request-comment@v2 | ||||
|       with: | ||||
|         number: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|         delete: true | ||||
| 
 | ||||
|     # Posts a notification to Slack if a PR has a breaking change and it did not have a breaking change before | ||||
|     - name: Post to Slack | ||||
|       id: slack | ||||
|       if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && steps.levitate-run.outputs.shouldSkip != 'true' && env.HAS_SECRETS | ||||
|       uses: slackapi/slack-github-action@v1.24.0 | ||||
|       with: | ||||
|         payload: | | ||||
|           { | ||||
|             "pr_link": "https://github.com/grafana/grafana/pull/${{ steps.levitate-run.outputs.pr_number }}", | ||||
|             "pr_number": "${{ steps.levitate-run.outputs.pr_number }}", | ||||
|             "job_link": "${{ steps.levitate-run.outputs.job_link }}", | ||||
|             "reporting_job_link": "${{ github.event.workflow_run.html_url }}", | ||||
|             "message": "${{ steps.levitate-run.outputs.message }}" | ||||
|           } | ||||
|       env: | ||||
|         SLACK_WEBHOOK_URL: ${{ secrets.SLACK_LEVITATE_WEBHOOK_URL }} | ||||
|         HAS_SECRETS: ${{ (github.repository == 'grafana/grafana' || secrets.SLACK_LEVITATE_WEBHOOK_URL != '') || '' }} | ||||
| 
 | ||||
|     # Add the label | ||||
|     - name: Add "levitate breaking change" label | ||||
|       if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|       with: | ||||
|         github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|         script: | | ||||
|           await github.rest.issues.addLabels({ | ||||
|             issue_number: process.env.PR_NUMBER, | ||||
|             owner: context.repo.owner, | ||||
|             repo: context.repo.repo, | ||||
|             labels: ['levitate breaking change'] | ||||
|           }) | ||||
| 
 | ||||
|     # Remove label (no more breaking changes) | ||||
|     - name: Remove "levitate breaking change" label | ||||
|       if: steps.levitate-run.outputs.exit_code == 0 && steps.does-label-exist.outputs.result == 1 && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|       with: | ||||
|         github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|         script: | | ||||
|           await github.rest.issues.removeLabel({ | ||||
|             issue_number: process.env.PR_NUMBER, | ||||
|             owner: context.repo.owner, | ||||
|             repo: context.repo.repo, | ||||
|             name: 'levitate breaking change' | ||||
|           }) | ||||
| 
 | ||||
|     # Add reviewers | ||||
|     # This is very weird, the actual request goes through (comes back with a 201), but does not assign the team. | ||||
|     # Related issue: https://github.com/renovatebot/renovate/issues/1908 | ||||
|     - name: Add "grafana/plugins-platform-frontend" as a reviewer | ||||
|       if: steps.levitate-run.outputs.exit_code && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|       with: | ||||
|         github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|         script: | | ||||
|           await github.rest.pulls.requestReviewers({ | ||||
|             pull_number: process.env.PR_NUMBER, | ||||
|             owner: context.repo.owner, | ||||
|             repo: context.repo.repo, | ||||
|             reviewers: [], | ||||
|             team_reviewers: ['grafana/plugins-platform-frontend'] | ||||
|           }); | ||||
| 
 | ||||
|     # Remove reviewers (no more breaking changes) | ||||
|     - name: Remove "grafana/plugins-platform-frontend" from the list of reviewers | ||||
|       if: steps.levitate-run.outputs.exit_code == 0 && steps.levitate-run.outputs.shouldSkip != 'true' | ||||
|       uses: actions/github-script@v6 | ||||
|       env: | ||||
|         PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }} | ||||
|       with: | ||||
|         github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|         script: | | ||||
|           await github.rest.pulls.removeRequestedReviewers({ | ||||
|             pull_number: process.env.PR_NUMBER, | ||||
|             owner: context.repo.owner, | ||||
|             repo: context.repo.repo, | ||||
|             reviewers: [], | ||||
|             team_reviewers: ['grafana/plugins-platform-frontend'] | ||||
|           }); | ||||
| 
 | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue