diff --git a/changelog/README.md b/changelog/README.md index afbfbc5..f889bdf 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -138,9 +138,12 @@ submit workflow (write permissions, via workflow_run) │ └── posts PR comment with view/edit links │ ├── if "no-label": - │ └── posts PR comment listing available labels + │ └── posts PR comment listing available type labels and skip labels │ - └── otherwise (skipped, manually-edited): no-op + ├── if "skipped" (label rules): + │ └── posts PR comment confirming changelog was skipped + │ + └── otherwise (manually-edited): no-op ``` The evaluate logic runs twice — once as a gate (with event-specific checks like body-only edit and bot-loop detection), and once in the trusted submit context to drive behavior. This is intentional: the second evaluation uses fresh PR data from the API, so it correctly handles label or title changes between the two runs. The submit workflow runs for any non-cancelled validate conclusion, so it can post actionable feedback (e.g., listing available labels) even when validate fails. @@ -171,6 +174,8 @@ rules: When all products are blocked by the create rules, the validate action passes with `skipped` status (so CI stays green) and the submit action exits without generating. If no matching type label is found (including when labels exist but none correspond to a configured type or skip rule), validate fails with `no-label` and submit posts a comment listing the available labels. You can also use `include` mode or per-product overrides. See [Rules for creation and publishing](https://elastic.github.io/docs-builder/contribute/changelog/#rules-for-creation-and-publishing) for the full reference. +When a PR has no type label, the failure comment also lists the available skip labels (if configured), so contributors know how to opt out of changelog generation. + ## Manual edits If a human edits the changelog file directly (i.e., the last commit to the changelog file is not from `github-actions[bot]`), the automation will not overwrite it. This lets authors customize the generated entry without it being regenerated on the next push. diff --git a/changelog/submit/action.yml b/changelog/submit/action.yml index fff2460..e7e5f11 100644 --- a/changelog/submit/action.yml +++ b/changelog/submit/action.yml @@ -251,9 +251,22 @@ runs: PR_NUMBER: ${{ steps.pr.outputs.number }} LABEL_TABLE: ${{ steps.evaluate.outputs.label-table }} PRODUCT_LABEL_TABLE: ${{ steps.evaluate.outputs.product-label-table }} + SKIP_LABELS: ${{ steps.evaluate.outputs.skip-labels }} CONFIG_FILE: ${{ inputs.config }} with: github-token: ${{ inputs.github-token }} script: | const script = require('${{ github.action_path }}/scripts/post-failure-comment.js'); await script({ github, context, core }); + + - name: Post skipped comment + if: steps.evaluate.outputs.status == 'skipped' + uses: actions/github-script@v8 + env: + PR_NUMBER: ${{ steps.pr.outputs.number }} + SKIP_LABELS: ${{ steps.evaluate.outputs.skip-labels }} + with: + github-token: ${{ inputs.github-token }} + script: | + const script = require('${{ github.action_path }}/scripts/post-skipped-comment.js'); + await script({ github, context, core }); diff --git a/changelog/submit/scripts/post-failure-comment.js b/changelog/submit/scripts/post-failure-comment.js index 7ac362b..f77fb32 100644 --- a/changelog/submit/scripts/post-failure-comment.js +++ b/changelog/submit/scripts/post-failure-comment.js @@ -5,6 +5,7 @@ module.exports = async ({ github, context, core }) => { const configFile = process.env.CONFIG_FILE || 'docs/changelog.yml'; const labelRows = process.env.LABEL_TABLE || ''; const productLabelRows = process.env.PRODUCT_LABEL_TABLE || ''; + const skipLabels = process.env.SKIP_LABELS || ''; let labelSection; if (labelRows.trim()) { @@ -28,14 +29,23 @@ module.exports = async ({ github, context, core }) => { ].join('\n'); } + let skipSection; + if (skipLabels.trim()) { + const formatted = skipLabels.split(',').map(l => `\`${l.trim()}\``).join(', '); + skipSection = `\n⏭️ To skip changelog generation, add one of these labels: ${formatted}`; + } else { + skipSection = `\n⏭️ No skip labels are configured. To allow skipping changelog generation, add a label to \`rules.create.exclude\` in \`${configFile}\`.`; + } + const body = [ TITLE, '', '⚠️ **Cannot generate changelog:** no matching type label found on this PR.', labelSection, productSection, + skipSection, '', - `🔖 To skip changelog generation or configure label rules, see \`${configFile}\`.`, + `📄 See \`${configFile}\` for the full changelog configuration.`, ].join('\n'); await upsertComment({ github, context, prNumber, body }); diff --git a/changelog/submit/scripts/post-skipped-comment.js b/changelog/submit/scripts/post-skipped-comment.js new file mode 100644 index 0000000..94d4433 --- /dev/null +++ b/changelog/submit/scripts/post-skipped-comment.js @@ -0,0 +1,19 @@ +const { TITLE, upsertComment } = require('./comment-helper'); + +module.exports = async ({ github, context, core }) => { + const prNumber = parseInt(process.env.PR_NUMBER, 10); + const skipLabels = process.env.SKIP_LABELS || ''; + + const bodyParts = [ + TITLE, + '', + '⏭️ Changelog generation was skipped for this pull request.', + ]; + + if (skipLabels.trim()) { + const formatted = skipLabels.split(',').map(l => `\`${l.trim()}\``).join(', '); + bodyParts.push('', `Matched skip label(s): ${formatted}`); + } + + await upsertComment({ github, context, prNumber, body: bodyParts.join('\n') }); +};