docs-v2/.github/workflows/sync-plugins.yml

353 lines
14 KiB
YAML

name: Sync Plugin Documentation
on:
issues:
types: [opened]
workflow_dispatch:
inputs:
plugins:
description: 'Plugin names to sync (comma-separated, or "all")'
required: true
default: 'all'
source_commit:
description: 'influxdb3_plugins commit SHA or branch'
required: false
default: 'master'
permissions:
contents: write
pull-requests: write
issues: write
jobs:
sync-plugins:
runs-on: ubuntu-latest
# Only run on issues with sync-plugin-docs label or manual dispatch
if: |
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issues' && contains(github.event.issue.labels.*.name, 'sync-plugin-docs'))
steps:
- name: Parse issue inputs
id: parse-inputs
if: github.event_name == 'issues'
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const body = issue.body || '';
// Extract plugins and source_commit from issue body
const pluginsMatch = body.match(/### Plugin Names\s*\n\s*(.+)/);
const commitMatch = body.match(/### Source Commit\/Branch\s*\n\s*(.+)/);
const plugins = pluginsMatch ? pluginsMatch[1].trim() : 'all';
const sourceCommit = commitMatch ? commitMatch[1].trim() : 'master';
core.setOutput('plugins', plugins);
core.setOutput('source_commit', sourceCommit);
core.setOutput('issue_number', issue.number);
- name: Set workflow inputs
id: inputs
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "plugins=${{ github.event.inputs.plugins }}" >> $GITHUB_OUTPUT
echo "source_commit=${{ github.event.inputs.source_commit }}" >> $GITHUB_OUTPUT
echo "issue_number=" >> $GITHUB_OUTPUT
else
echo "plugins=${{ steps.parse-inputs.outputs.plugins }}" >> $GITHUB_OUTPUT
echo "source_commit=${{ steps.parse-inputs.outputs.source_commit }}" >> $GITHUB_OUTPUT
echo "issue_number=${{ steps.parse-inputs.outputs.issue_number }}" >> $GITHUB_OUTPUT
fi
- name: Update issue status
if: steps.inputs.outputs.issue_number != ''
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ steps.inputs.outputs.issue_number }},
body: '🔄 Plugin sync started...\n\nPlugins: `${{ steps.inputs.outputs.plugins }}`\nSource: `${{ steps.inputs.outputs.source_commit }}`'
});
- name: Checkout docs-v2
uses: actions/checkout@v4
with:
path: docs-v2
token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout influxdb3_plugins (sparse)
run: |
git clone --filter=blob:none --sparse https://github.com/influxdata/influxdb3_plugins.git influxdb3_plugins
cd influxdb3_plugins
git sparse-checkout set influxdata/ scripts/
git checkout ${{ steps.inputs.outputs.source_commit }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'
cache-dependency-path: docs-v2/yarn.lock
- name: Install dependencies
run: |
cd docs-v2
CYPRESS_INSTALL_BINARY=0 yarn install
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Validate plugin READMEs
id: validate
run: |
cd influxdb3_plugins
# Determine which plugins to validate
if [[ "${{ steps.inputs.outputs.plugins }}" == "all" ]]; then
PLUGINS=""
else
PLUGINS="${{ steps.inputs.outputs.plugins }}"
fi
# Run validation
if [[ -n "$PLUGINS" ]]; then
echo "Validating specific plugins: $PLUGINS"
python scripts/validate_readme.py --plugins "$PLUGINS" 2>&1 | tee validation.log
else
echo "Validating all plugins"
python scripts/validate_readme.py 2>&1 | tee validation.log
fi
# Check if validation passed
if [[ ${PIPESTATUS[0]} -eq 0 ]]; then
echo "validation_passed=true" >> $GITHUB_OUTPUT
else
echo "validation_passed=false" >> $GITHUB_OUTPUT
fi
- name: Report validation failure
if: steps.validate.outputs.validation_passed == 'false'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let validationLog = '';
try {
validationLog = fs.readFileSync('influxdb3_plugins/validation.log', 'utf8');
} catch (e) {
validationLog = 'Could not read validation log';
}
const issueNumber = '${{ steps.inputs.outputs.issue_number }}';
if (issueNumber) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber),
body: `❌ **Validation Failed**
Plugin READMEs do not meet template requirements. Please fix the following issues in influxdb3_plugins:
\`\`\`
${validationLog}
\`\`\`
See [README_TEMPLATE.md](https://github.com/influxdata/influxdb3_plugins/blob/master/README_TEMPLATE.md) for requirements.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber),
state: 'closed',
labels: ['sync-plugin-docs', 'validation-failed']
});
}
core.setFailed('Plugin validation failed');
- name: Transform plugin documentation
if: steps.validate.outputs.validation_passed == 'true'
run: |
cd docs-v2
# Set PLUGIN_DIR for the transformation script
export INFLUXDB3_PLUGINS_PATH="../influxdb3_plugins"
# Run the transformation
if [[ "${{ steps.inputs.outputs.plugins }}" == "all" ]]; then
node helper-scripts/influxdb3-plugins/port_to_docs.js
else
# Transform specific plugins
IFS=',' read -ra PLUGIN_ARRAY <<< "${{ steps.inputs.outputs.plugins }}"
for plugin in "${PLUGIN_ARRAY[@]}"; do
plugin=$(echo "$plugin" | xargs) # trim whitespace
echo "Transforming plugin: $plugin"
node helper-scripts/influxdb3-plugins/port_to_docs.js --plugin "$plugin"
done
fi
- name: Build Hugo site
run: |
cd docs-v2
npx hugo --quiet --minify
- name: Setup Playwright
run: |
cd docs-v2
npx playwright install chromium
- name: Generate screenshots
id: screenshots
run: |
cd docs-v2
# Start Hugo server in background
npx hugo server --bind 0.0.0.0 --port 1313 --quiet &
HUGO_PID=$!
# Wait for server to start
sleep 10
# Create screenshots directory
mkdir -p plugin-screenshots
# Generate screenshots for changed plugin pages
node -e "
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
async function captureScreenshots() {
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1200, height: 800 } });
// Find changed plugin files
const glob = require('glob');
const pluginFiles = glob.sync('content/shared/influxdb3-plugins/plugins-library/**/*.md');
for (const file of pluginFiles) {
const pluginName = path.basename(file, '.md');
const url = \`http://localhost:1313/influxdb3/core/reference/plugins/\${pluginName}/\`;
try {
console.log(\`Capturing screenshot for \${pluginName}\`);
await page.goto(url, { waitUntil: 'networkidle' });
await page.screenshot({
path: \`plugin-screenshots/\${pluginName}.png\`,
fullPage: true
});
} catch (error) {
console.log(\`Could not capture \${pluginName}: \${error.message}\`);
}
}
await browser.close();
}
captureScreenshots().catch(console.error);
"
# Stop Hugo server
kill $HUGO_PID
# List generated screenshots
ls -la plugin-screenshots/ || echo "No screenshots generated"
echo "screenshots_generated=$(ls plugin-screenshots/ 2>/dev/null | wc -l)" >> $GITHUB_OUTPUT
- name: Create Pull Request
if: steps.validate.outputs.validation_passed == 'true'
id: create-pr
uses: peter-evans/create-pull-request@v5
with:
path: docs-v2
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: |
sync: update plugin documentation from influxdb3_plugins@${{ steps.inputs.outputs.source_commit }}
Plugins: ${{ steps.inputs.outputs.plugins }}
branch: sync-plugins-${{ github.run_number }}
title: "Sync plugin documentation: ${{ steps.inputs.outputs.plugins }}"
body: |
## Plugin Documentation Sync
**Source**: influxdb3_plugins@${{ steps.inputs.outputs.source_commit }}
**Plugins**: ${{ steps.inputs.outputs.plugins }}
**Triggered by**: ${{ github.event_name == 'issues' && format('Issue #{0}', steps.inputs.outputs.issue_number) || 'Manual workflow dispatch' }}
### Changes Made
- ✅ Validated source READMEs against template requirements
- 🔄 Transformed content for docs-v2 compatibility
- 🖼️ Generated ${{ steps.screenshots.outputs.screenshots_generated }} plugin page screenshots
### Transformations Applied
- Removed emoji metadata (already in plugin JSON metadata)
- Converted relative links to GitHub URLs
- Added Hugo product shortcodes (`{{% product-name %}}`)
- Added standard logging section
- Updated support sections with docs-v2 format
### Screenshots
Plugin page previews are available in the `plugin-screenshots/` directory (if any were generated).
### Review Checklist
- [ ] All plugin pages render correctly
- [ ] GitHub links resolve properly
- [ ] Product shortcodes display correctly
- [ ] Code examples are properly formatted
- [ ] Support sections link correctly
---
*This PR was automatically generated by the plugin sync workflow.*
- name: Update issue with success
if: steps.validate.outputs.validation_passed == 'true' && steps.inputs.outputs.issue_number != ''
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ steps.inputs.outputs.issue_number }},
body: `✅ **Plugin sync completed successfully!**
**Pull Request**: #${{ steps.create-pr.outputs.pull-request-number }}
**Plugins synced**: ${{ steps.inputs.outputs.plugins }}
**Source commit**: ${{ steps.inputs.outputs.source_commit }}
**Screenshots generated**: ${{ steps.screenshots.outputs.screenshots_generated }}
The PR is ready for review and includes all necessary transformations and validations.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ steps.inputs.outputs.issue_number }},
state: 'closed',
labels: ['sync-plugin-docs', 'completed']
});
- name: Report failure
if: failure() && steps.inputs.outputs.issue_number != ''
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ steps.inputs.outputs.issue_number }},
body: `❌ **Plugin sync failed**
Please check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
You may need to:
- Check that the source commit exists
- Verify plugin names are correct
- Ensure all validation requirements are met`
});