-
Notifications
You must be signed in to change notification settings - Fork 4
Add docs-changelog-commit and docs-changelog-generate workflows and accompanying actions #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
0e7290a
490dab8
0f5eeb2
feba56f
e90995f
252a590
583ba51
60ebc8a
26b0adf
2966964
116c92f
199da2d
38575bc
5a7f7ce
dce6d29
d8faffe
5f06856
981d2f8
b86ad95
2e7371a
f9a6523
7385214
9e55057
b723a0c
aad75f3
d424f92
76f2baa
5daa6d1
a48024a
8028d84
fa5cce5
a67c45a
1d925fa
dd9ba2d
9d79b3c
c7f963e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| name: Changelog generate | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| config: | ||
| description: 'Path to changelog.yml configuration file' | ||
| type: string | ||
| default: 'docs/changelog.yml' | ||
|
|
||
| concurrency: | ||
| group: changelog-${{ github.event.pull_request.number || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| generate: | ||
| if: github.event.pull_request.state == 'open' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Generate changelog | ||
| uses: elastic/docs-actions/changelog/generate@v1 | ||
| with: | ||
| config: ${{ inputs.config }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| name: Changelog submit | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| comment-only: | ||
| description: 'Post changelog as a PR comment instead of committing to the branch' | ||
| type: boolean | ||
| default: false | ||
|
|
||
| concurrency: | ||
| group: changelog-submit-${{ github.event.workflow_run.head_branch || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| submit: | ||
| if: > | ||
| github.event.workflow_run.event == 'pull_request' | ||
| && github.event.workflow_run.conclusion == 'success' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Submit changelog | ||
| uses: elastic/docs-actions/changelog/submit@v1 | ||
| with: | ||
| comment-only: ${{ inputs.comment-only }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| # Changelog automation | ||
|
|
||
| Automatically generate and submit changelog entries for pull requests. | ||
|
|
||
| When a PR is opened or labeled, the system generates a changelog YAML file based on the PR title and type label, commits it to the PR branch, and posts a comment with a link to view or edit the entry. | ||
|
|
||
| ## Setup | ||
|
|
||
| ### 1. Add the changelog configuration | ||
|
|
||
| Create `docs/changelog.yml` in your repository by running `docs-builder changelog init`. | ||
|
|
||
| By default, you will get a file with this structure: | ||
|
|
||
| ```yaml | ||
| pivot: | ||
| types: | ||
| enhancement: | ||
| labels: | ||
| - enhancement | ||
| - feature | ||
| bug: | ||
| labels: | ||
| - bug | ||
| breaking: | ||
| labels: | ||
| - breaking | ||
| deprecation: | ||
| labels: | ||
| - deprecation | ||
| ``` | ||
|
|
||
| Each key under `pivot.types` is a changelog type. The `labels` list defines which GitHub labels map to that type. When a PR has one of these labels, the changelog entry is categorized accordingly. | ||
|
|
||
| ### 2. Create the workflows | ||
|
|
||
| Add two workflow files to your repository: | ||
|
|
||
| **`.github/workflows/changelog-generate.yml`** | ||
|
|
||
| ```yaml | ||
| name: changelog-generate | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: | ||
| - opened | ||
| - synchronize | ||
| - reopened | ||
| - edited | ||
| - labeled | ||
| - unlabeled | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| generate: | ||
| uses: elastic/docs-actions/.github/workflows/changelog-generate.yml@v1 | ||
| ``` | ||
|
|
||
| **`.github/workflows/changelog-submit.yml`** | ||
|
|
||
| ```yaml | ||
| name: changelog-submit | ||
|
|
||
| on: | ||
| workflow_run: | ||
| workflows: [changelog-generate] | ||
| types: | ||
| - completed | ||
|
|
||
| permissions: | ||
| actions: read | ||
| contents: write | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
|
cotti marked this conversation as resolved.
|
||
| submit: | ||
| uses: elastic/docs-actions/.github/workflows/changelog-submit.yml@v1 | ||
| ``` | ||
|
|
||
| > **Important:** The `name` in the generate workflow (`changelog-generate`) must match the `workflows:` reference in the submit workflow. If you rename one, rename the other. | ||
|
|
||
| The two-workflow design is required because the generate workflow runs with read-only permissions (from the PR context), while the submit workflow runs with write permissions (from `workflow_run`, which uses the base branch's permissions). This is a [standard pattern](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) for safely handling PR branches, including those from forks. | ||
|
|
||
| ### 3. Create the labels | ||
|
|
||
| Make sure the GitHub labels referenced in your `docs/changelog.yml` exist in your repository. You can control which PRs generate changelog entries using `rules.create` in your config -- either by excluding PRs with certain labels or by requiring specific labels to be present. For details, see [Rules for creation and publishing](https://elastic.github.io/docs-builder/contribute/changelog/#rules-for-creation-and-publishing). | ||
|
|
||
| ## How it works | ||
|
|
||
| ``` | ||
| PR opened/labeled/title edited | ||
| | | ||
| v | ||
| generate workflow (read-only) | ||
| | | ||
| +-- skip if labels match rules.create exclusion rules | ||
| +-- skip if last commit is from the bot (prevents loops) | ||
| +-- skip if changelog file was manually edited | ||
| +-- skip if only the PR body was edited (not the title) | ||
| | | ||
| +-- resolves title and type from PR metadata + config | ||
| +-- runs: docs-builder changelog add | ||
| +-- uploads result as artifact | ||
| | | ||
| v | ||
| submit workflow (write permissions, via workflow_run) | ||
| | | ||
| +-- downloads artifact | ||
| +-- re-validates PR state (labels, head SHA, fork detection) | ||
| +-- commits changelog file to PR branch | ||
| +-- posts PR comment with view/edit links | ||
| | | ||
| +-- fork PRs: posts changelog as comment instead | ||
| +-- no-label PRs: posts comment listing available labels | ||
| ``` | ||
|
|
||
| ### Comment-only mode | ||
|
|
||
| If you prefer not to have bot commits on your PR branches, pass `comment-only: true` to the submit workflow. The changelog content will be posted as a PR comment instead: | ||
|
|
||
| ```yaml | ||
| jobs: | ||
| submit: | ||
| uses: elastic/docs-actions/.github/workflows/changelog-submit.yml@v1 | ||
| with: | ||
| comment-only: true | ||
| ``` | ||
|
|
||
| Fork PRs automatically use comment-only mode since the workflow token cannot push to fork branches. | ||
|
|
||
| ## Skipping changelog generation | ||
|
|
||
| Configure `rules.create` in your `docs/changelog.yml` to control which PRs generate changelog entries. For example, to skip PRs with a `changelog:skip` label: | ||
|
|
||
| ```yaml | ||
| rules: | ||
| create: | ||
| exclude: "changelog:skip" | ||
| ``` | ||
|
|
||
| When all products are blocked by the create rules, the generate action will exit early and no artifact or commit is produced. 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. | ||
|
|
||
| ## Manual edits | ||
|
|
||
| If a human edits the changelog file directly (i.e., the last commit to `docs/changelog/{PR_NUMBER}.yaml` 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. | ||
|
cotti marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Output | ||
|
|
||
| Each PR produces a file at `docs/changelog/{PR_NUMBER}.yaml` on the PR branch. These files are consumed by `docs-builder` during documentation builds to produce a rendered changelog page. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Per Martijn's comments elsewhere, I think this needs to accommodate the different file output names (https://elastic.github.io/docs-builder/contribute/changelog/#filenames) and file output directories (per config file). IMO we should expect them to have those choices defined in the config file rather than trying to support via command options.
cotti marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| name: Changelog generate | ||
| description: > | ||
| Generate a changelog entry for a pull request using docs-builder. | ||
| Handles setup, changelog generation, artifact upload, metadata creation and PR guard checks. | ||
|
|
||
| inputs: | ||
| config: | ||
| description: 'Path to changelog.yml configuration file' | ||
| default: 'docs/changelog.yml' | ||
| strip-title-prefix: | ||
| description: 'Remove [Prefix]: from PR titles' | ||
| default: 'true' | ||
| github-token: | ||
| description: 'GitHub token for API access' | ||
| default: '${{ github.token }}' | ||
|
|
||
| outputs: | ||
| status: | ||
| description: 'Result: success, no-label, no-title, error, manually-edited, or skipped' | ||
| value: ${{ steps.resolve.outputs.status }} | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup docs-builder | ||
| uses: elastic/docs-actions/docs-builder/setup@v1 | ||
| with: | ||
| version: latest | ||
| github-token: ${{ inputs.github-token }} | ||
|
|
||
| - name: Evaluate PR | ||
| id: evaluate | ||
| shell: bash | ||
| env: | ||
| GITHUB_TOKEN: ${{ inputs.github-token }} | ||
| CONFIG_FILE: ${{ inputs.config }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| PR_TITLE: ${{ github.event.pull_request.title }} | ||
| PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} | ||
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| EVENT_ACTION: ${{ github.event.action }} | ||
| TITLE_CHANGED: ${{ github.event.changes.title != null }} | ||
| STRIP_PREFIX: ${{ inputs.strip-title-prefix }} | ||
| run: | | ||
|
cotti marked this conversation as resolved.
Outdated
|
||
| TITLE_FLAG="" | ||
| if [ "$TITLE_CHANGED" = "true" ]; then | ||
| TITLE_FLAG="--title-changed" | ||
| fi | ||
|
|
||
| PREFIX_FLAG="" | ||
| if [ "$STRIP_PREFIX" = "true" ]; then | ||
| PREFIX_FLAG="--strip-title-prefix" | ||
| fi | ||
|
|
||
| docs-builder changelog evaluate-pr \ | ||
| --config "$CONFIG_FILE" \ | ||
| --owner "${{ github.repository_owner }}" \ | ||
| --repo "${{ github.event.repository.name }}" \ | ||
| --pr-number "$PR_NUMBER" \ | ||
| --pr-title "$PR_TITLE" \ | ||
| --pr-labels "$PR_LABELS" \ | ||
| --head-ref "$HEAD_REF" \ | ||
| --head-sha "$HEAD_SHA" \ | ||
| --event-action "$EVENT_ACTION" \ | ||
| $TITLE_FLAG \ | ||
| $PREFIX_FLAG | ||
|
|
||
| - name: Run changelog add | ||
| id: generate | ||
| if: steps.evaluate.outputs.should-generate == 'true' | ||
| shell: bash | ||
| env: | ||
| GITHUB_TOKEN: ${{ inputs.github-token }} | ||
| CONFIG_FILE: ${{ inputs.config }} | ||
| run: | | ||
| mkdir -p /tmp/changelog-staging | ||
| docs-builder changelog add \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want this command to generate PR-number filenames, it'll also need the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call, thank you! |
||
| --concise \ | ||
| --config "$CONFIG_FILE" \ | ||
| --output /tmp/changelog-staging | ||
|
|
||
| - name: Prepare artifact | ||
| if: always() && steps.evaluate.outputs.should-upload == 'true' | ||
| shell: bash | ||
| env: | ||
| GITHUB_TOKEN: ${{ inputs.github-token }} | ||
| CONFIG_FILE: ${{ inputs.config }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| EVALUATE_STATUS: ${{ steps.evaluate.outputs.status }} | ||
| GENERATE_OUTCOME: ${{ steps.generate.outcome }} | ||
| LABEL_TABLE: ${{ steps.evaluate.outputs.label-table }} | ||
| run: | | ||
| docs-builder changelog prepare-artifact \ | ||
| --staging-dir /tmp/changelog-staging \ | ||
| --output-dir /tmp/changelog-result \ | ||
| --evaluate-status "$EVALUATE_STATUS" \ | ||
| --generate-outcome "${GENERATE_OUTCOME:-skipped}" \ | ||
| --pr-number "$PR_NUMBER" \ | ||
| --head-ref "$HEAD_REF" \ | ||
| --head-sha "$HEAD_SHA" \ | ||
| --config "$CONFIG_FILE" \ | ||
| ${LABEL_TABLE:+--label-table "$LABEL_TABLE"} | ||
|
|
||
| - name: Upload artifact | ||
| if: always() && steps.evaluate.outputs.should-upload == 'true' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: changelog-result | ||
| path: /tmp/changelog-result/ | ||
| retention-days: 1 | ||
|
|
||
| - name: Resolve generation outcome | ||
| id: resolve | ||
| if: always() | ||
| shell: bash | ||
| run: | | ||
| STATUS="${{ steps.evaluate.outputs.status }}" | ||
| if [ "$STATUS" = "proceed" ]; then | ||
| if [ "${{ steps.generate.outcome }}" = "success" ]; then | ||
| STATUS="success" | ||
| else | ||
| STATUS="error" | ||
| fi | ||
| fi | ||
| STATUS="${STATUS:-skipped}" | ||
| echo "status=$STATUS" >> "$GITHUB_OUTPUT" | ||
|
|
||
| case "$STATUS" in | ||
| no-title) | ||
| echo "::error::PR has no title. Cannot generate a changelog entry without a title." | ||
| exit 1 | ||
| ;; | ||
| error) | ||
| echo "::error::Changelog generation failed unexpectedly." | ||
| exit 1 | ||
| ;; | ||
| esac | ||
Uh oh!
There was an error while loading. Please reload this page.