grafana/.github/workflows/detect-plugin-extension-cha...

156 lines
6.2 KiB
YAML

---
name: Detect Plugin Extension Changes
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
on:
pull_request:
branches:
- 'main'
paths:
- 'packages/**'
- 'public/**'
env:
# Space-separated list of keywords referring to plugin extensions
PLUGIN_EXTENSION_KEYWORDS: "usePluginLinks, usePluginComponent, usePluginComponents, usePluginFunctions, PluginExtensionPoints"
jobs:
detect-plugin-extension-changes:
name: Detect Plugin Extension Changes
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Check for plugin extension changes
id: check-changes
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
const fs = require('fs');
// Plugin extension keywords from environment
const keywords = process.env.PLUGIN_EXTENSION_KEYWORDS.split(',');
const baseSha = '${{ github.event.pull_request.base.sha }}';
const headSha = '${{ github.event.pull_request.head.sha }}';
console.log('Checking for plugin extension changes...');
console.log('Keywords:', keywords);
// Get changed files in packages/ and public/ directories
let changedFiles = [];
const diffOutput = execSync(
`git diff --name-only ${baseSha}...${headSha} -- packages/ public/`,
{ encoding: 'utf8' }
).trim();
if (diffOutput) {
changedFiles = diffOutput.split('\n').filter(file => {
// Validate file path and ensure it's in target directories
return file.match(/^(packages\/|public\/)/) &&
file.match(/^[a-zA-Z0-9._/-]+$/) &&
fs.existsSync(file);
});
}
console.log('Changed files to check:', changedFiles);
// Check each file for plugin extension keywords
const filesWithChanges = new Set();
let hasPluginExtensionChanges = false;
for (const file of changedFiles) {
try {
// Get the diff for this specific file
const fileDiff = execSync(
`git diff ${baseSha}...${headSha} -- "${file}"`,
{ encoding: 'utf8' }
);
// Check if any keywords are in the diff
for (const keyword of keywords) {
if (fileDiff.includes(keyword)) {
console.log(`Found ${keyword} in ${file}`);
filesWithChanges.add(file);
hasPluginExtensionChanges = true;
break; // Found at least one keyword, move to next file
}
}
} catch (error) {
console.log(`Error checking file ${file}:`, error.message);
}
}
// Set outputs
const filesArray = Array.from(filesWithChanges);
const formattedFiles = filesArray.length > 0
? '`' + filesArray.join('`\\n- `') + '`'
: '';
core.setOutput('plugin_extension_changes', hasPluginExtensionChanges.toString());
core.setOutput('formatted_changed_files', formattedFiles);
if (hasPluginExtensionChanges) {
console.log('The following files have changes that may affect plugin extensions:');
console.log(filesArray);
} else {
console.log('No changes detected in core Grafana extensions or extension points.');
}
- name: Send Slack Message via Payload
id: slack
if: steps.check-changes.outputs.plugin_extension_changes == 'true'
uses: grafana/shared-workflows/actions/send-slack-message@0941e3408fa4789fec9062c44a2a9e1832146ba6 #v2.0.1
with:
method: chat.postMessage
payload-templated: true
payload: |
{
"channel": "C031SLFH6G0",
"text": "Plugin Extension changes in core Grafana *PR:* <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }} :information_source:",
"icon_emoji": ":grot:",
"username": "Plugin Extension Bot",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Plugin Extensions:* possible changes to extension points in core Grafana."
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*PR:* <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}>\n*Job:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Job>\n*Author:* ${{ github.event.pull_request.user.login }}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*File(s) with changes:*\n- ${{ steps.check-changes.outputs.formatted_changed_files }}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*What to do?*\nMake sure that:\n- All extension point ids start with `grafana/`\n- All extension point ids are exposed via <https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/pluginExtensions.ts#L183|the `PluginExtensionPoints` enum in grafana-data>\n- Core Grafana is not registering extensions to extension points offered by plugins"
}
}
]
}