-
Notifications
You must be signed in to change notification settings - Fork 1
Add bundle action and reusable workflow #42
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
base: main
Are you sure you want to change the base?
Changes from all commits
cb3c68c
fa8354f
c31000b
4de3e84
6bfcfd9
e43c658
f86c77c
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,67 @@ | ||
| name: Changelog bundle | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| config: | ||
| description: 'Path to changelog.yml configuration file' | ||
| type: string | ||
| default: 'docs/changelog.yml' | ||
| release-version: | ||
| description: > | ||
| GitHub release tag used as the PR filter source (e.g. v9.2.0). | ||
| Mutually exclusive with report. | ||
| type: string | ||
| report: | ||
| description: > | ||
| Buildkite promotion report HTTPS URL or local file path. | ||
| Mutually exclusive with release-version. | ||
| type: string | ||
| output: | ||
| description: 'Output file path for the bundle (e.g. docs/releases/v9.2.0.yaml)' | ||
| type: string | ||
| required: true | ||
| base-branch: | ||
| description: 'Base branch for the pull request (defaults to repository default branch)' | ||
| type: string | ||
| repo: | ||
| description: 'GitHub repository name; falls back to bundle.repo in changelog.yml' | ||
| type: string | ||
| owner: | ||
| description: 'GitHub repository owner; falls back to bundle.owner in changelog.yml' | ||
| type: string | ||
|
|
||
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: changelog-bundle-${{ inputs.output }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
|
Member
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. Missing Add before permissions: {}
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. Changes from this report:
|
||
| generate: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - uses: elastic/docs-actions/changelog/bundle-create@v1 | ||
| with: | ||
| config: ${{ inputs.config }} | ||
| release-version: ${{ inputs.release-version }} | ||
| report: ${{ inputs.report }} | ||
| output: ${{ inputs.output }} | ||
| repo: ${{ inputs.repo }} | ||
| owner: ${{ inputs.owner }} | ||
| github-token: ${{ github.token }} | ||
|
|
||
| create-pr: | ||
| needs: generate | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| steps: | ||
| - uses: elastic/docs-actions/changelog/bundle-pr@v1 | ||
| with: | ||
| output: ${{ inputs.output }} | ||
| base-branch: ${{ inputs.base-branch }} | ||
| github-token: ${{ github.token }} | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -179,3 +179,113 @@ If a human edits the changelog file directly (i.e., the last commit to the chang | |||||||
| ## Output | ||||||||
|
|
||||||||
| Each PR produces a file at `docs/changelog/{filename}.yaml` on the PR branch (where the filename is determined by the `docs-builder changelog add` command). These files are consumed by `docs-builder` during documentation builds to produce a rendered changelog page. | ||||||||
|
|
||||||||
| ## Bundling changelogs | ||||||||
|
|
||||||||
| Individual changelog files accumulate on the default branch as PRs merge. The bundle action generates a fully-resolved YAML file containing only the changelog entries that match a given filter. Two filter sources are supported: | ||||||||
|
|
||||||||
| - **GitHub release version** (`release-version`) — pulls PR references directly from GitHub release notes. Used for stack and product releases triggered by `on: release`. | ||||||||
| - **Buildkite promotion report** (`report`) — extracts PR URLs from a promotion report. Used for serverless releases discovered by a scheduled workflow. | ||||||||
|
|
||||||||
| Exactly one filter source must be provided per invocation. The bundle always includes the full content of each matching entry (`--resolve`), so downstream consumers can render changelogs without access to the original files. | ||||||||
|
|
||||||||
| ### Prerequisites | ||||||||
|
|
||||||||
| Your `docs/changelog.yml` must include a `bundle` section so docs-builder knows where to find changelog files. Setting `bundle.repo` and `bundle.owner` ensures PR and issue links are generated correctly in the bundle output. | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| bundle: | ||||||||
| directory: docs/changelog | ||||||||
| ``` | ||||||||
|
|
||||||||
| The reusable workflow splits into two jobs with separate permissions: `generate` (read-only, produces the bundle artifact) and `create-pr` (write access, opens a pull request with the bundle file). | ||||||||
|
|
||||||||
| ### Setup | ||||||||
|
|
||||||||
| The bundle action supports two trigger patterns depending on your release process. | ||||||||
|
|
||||||||
| #### Stack / product releases (`on: release`) | ||||||||
|
|
||||||||
| When a GitHub release is published, the action uses `--release-version` to pull PR references directly from the release notes and filter changelog entries accordingly. The release tag provides the version for the output filename. | ||||||||
|
|
||||||||
| **`.github/workflows/changelog-bundle.yml`** | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| name: changelog-bundle | ||||||||
|
|
||||||||
| on: | ||||||||
| release: | ||||||||
| types: [published] | ||||||||
|
|
||||||||
| permissions: | ||||||||
| contents: write | ||||||||
| pull-requests: write | ||||||||
|
|
||||||||
| jobs: | ||||||||
| bundle: | ||||||||
| uses: elastic/docs-actions/.github/workflows/changelog-bundle.yml@v1 | ||||||||
| with: | ||||||||
| release-version: ${{ github.event.release.tag_name }} | ||||||||
| output: docs/releases/${{ github.event.release.tag_name }}.yaml | ||||||||
| ``` | ||||||||
|
|
||||||||
| The `github.event.release.tag_name` (e.g. `v9.2.0`) is passed as the release version filter and used to construct the output filename. If you prefer to strip the `v` prefix, you can do so in an earlier job step and pass the result as an input. | ||||||||
|
|
||||||||
| #### Serverless / scheduled releases (`on: schedule`) | ||||||||
|
|
||||||||
| When a Buildkite promotion report provides the list of PRs in a release, a scheduled workflow discovers the report and passes it to the bundle action. The output filename typically uses a date or timestamp. | ||||||||
|
|
||||||||
| **`.github/workflows/changelog-bundle.yml`** | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| name: changelog-bundle | ||||||||
|
|
||||||||
| on: | ||||||||
| schedule: | ||||||||
| # At 08:00 AM, Monday through Friday | ||||||||
| - cron: '0 8 * * 1-5' | ||||||||
|
Member
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.
Suggested change
I can never read cron syntax :D |
||||||||
| workflow_dispatch: | ||||||||
| inputs: | ||||||||
| report: | ||||||||
| description: 'Buildkite promotion report URL' | ||||||||
| required: true | ||||||||
| output: | ||||||||
| description: 'Output file path for the bundle' | ||||||||
| required: true | ||||||||
|
|
||||||||
| permissions: | ||||||||
| contents: write | ||||||||
| pull-requests: write | ||||||||
|
|
||||||||
| jobs: | ||||||||
| discover-report: | ||||||||
| runs-on: ubuntu-latest | ||||||||
| outputs: | ||||||||
| report-url: ${{ steps.discover.outputs.report-url }} | ||||||||
| release-date: ${{ steps.discover.outputs.release-date }} | ||||||||
| steps: | ||||||||
| - id: discover | ||||||||
| run: echo "# your logic to find the latest promotion report" | ||||||||
|
|
||||||||
| bundle: | ||||||||
| needs: discover-report | ||||||||
| uses: elastic/docs-actions/.github/workflows/changelog-bundle.yml@v1 | ||||||||
| with: | ||||||||
| report: ${{ needs.discover-report.outputs.report-url }} | ||||||||
| output: docs/releases/${{ needs.discover-report.outputs.release-date }}.yaml | ||||||||
| ``` | ||||||||
|
|
||||||||
| #### Custom config path | ||||||||
|
|
||||||||
| If your changelog configuration is not at `docs/changelog.yml`, pass the path explicitly: | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| with: | ||||||||
| config: path/to/changelog.yml | ||||||||
| release-version: ${{ github.event.release.tag_name }} | ||||||||
| output: docs/releases/${{ github.event.release.tag_name }}.yaml | ||||||||
| ``` | ||||||||
|
|
||||||||
| ### Output | ||||||||
|
|
||||||||
| The reusable workflow opens a pull request on a branch named `changelog-bundle/<bundle-name>` (e.g. `changelog-bundle/v9.2.0`). The PR contains the fully-resolved bundle file at the path specified by the `output` input. If a PR already exists for that branch, the bundle is updated in place. If the generated bundle is identical to what's already in the repository, no commit or PR is created. | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <!-- Generated by https://github.com/reakaleek/gh-action-readme --> | ||
| # <!--name-->changelog/bundle-create<!--/name--> | ||
| <!--description--> | ||
| Checks out the repository, runs docs-builder changelog bundle in Docker to generate a fully-resolved bundle file, and uploads the result as an artifact. Supports filtering by GitHub release version or Buildkite promotion report. Uses --network none for report mode. | ||
| <!--/description--> | ||
|
|
||
| ## Inputs | ||
| <!--inputs--> | ||
| | Name | Description | Required | Default | | ||
| |-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------------------| | ||
| | `config` | Path to changelog.yml configuration file | `false` | `docs/changelog.yml` | | ||
| | `release-version` | GitHub release tag used as the PR filter source (e.g. v9.2.0). Mutually exclusive with report. Requires repo to be set in changelog.yml or via repo input. | `false` | | | ||
| | `report` | Buildkite promotion report URL or local file path used as the PR filter source. Mutually exclusive with release-version. Local paths must be relative to repo root. | `false` | | | ||
| | `output` | Output file path for the bundle, relative to the repo root (e.g. docs/releases/v9.2.0.yaml). Must end in .yml or .yaml. | `true` | | | ||
|
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. It might be nice (in follow-up PR?) to make the github action support profiles. Then more of these options could be picked up automatically from the config file (e.g. |
||
| | `repo` | GitHub repository name. Falls back to bundle.repo in changelog.yml. | `false` | | | ||
| | `owner` | GitHub repository owner. Falls back to bundle.owner in changelog.yml, then to elastic. | `false` | | | ||
| | `github-token` | GitHub token (needed for release-version to access GitHub API) | `false` | `${{ github.token }}` | | ||
| <!--/inputs--> | ||
|
|
||
| ## Outputs | ||
| <!--outputs--> | ||
| | Name | Description | | ||
| |------|-------------| | ||
| <!--/outputs--> | ||
|
|
||
| ## Usage | ||
| <!--usage action="elastic/docs-actions/changelog/bundle-create" version="v1"--> | ||
| ```yaml | ||
| steps: | ||
| - uses: elastic/docs-actions/changelog/bundle-create@v1 | ||
| with: | ||
| release-version: v9.2.0 | ||
| output: docs/releases/v9.2.0.yaml | ||
| ``` | ||
| <!--/usage--> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| name: Changelog bundle create | ||
| description: > | ||
| Checks out the repository, runs docs-builder changelog bundle in Docker | ||
| to generate a fully-resolved bundle file, and uploads the result as an | ||
| artifact. Supports filtering by GitHub release version or Buildkite | ||
| promotion report. Uses --network none for report mode. | ||
|
|
||
| inputs: | ||
| config: | ||
| description: 'Path to changelog.yml configuration file' | ||
| default: 'docs/changelog.yml' | ||
| release-version: | ||
| description: > | ||
| GitHub release tag used as the PR filter source (e.g. v9.2.0). | ||
| Mutually exclusive with report. Requires repo to be set in | ||
| changelog.yml (bundle.repo) or passed via the repo input. | ||
| report: | ||
| description: > | ||
| Buildkite promotion report URL or local file path used as the | ||
| PR filter source. Mutually exclusive with release-version. | ||
| Local paths must be relative to the repo root. | ||
| output: | ||
| description: > | ||
| Output file path for the bundle, relative to the repo root | ||
| (e.g. docs/releases/v9.2.0.yaml). Must end in .yml or .yaml. | ||
| required: true | ||
| repo: | ||
| description: > | ||
| GitHub repository name. Falls back to bundle.repo in changelog.yml. | ||
| owner: | ||
| description: > | ||
| GitHub repository owner. Falls back to bundle.owner in changelog.yml, | ||
| then to elastic. | ||
| artifact-name: | ||
| description: 'Name for the uploaded artifact (must match bundle-pr artifact-name)' | ||
| default: 'changelog-bundle' | ||
| github-token: | ||
| description: 'GitHub token (needed for release-version to access GitHub API)' | ||
| default: '${{ github.token }}' | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Generate changelog bundle | ||
| shell: bash | ||
| env: | ||
| CONFIG: ${{ inputs.config }} | ||
| RELEASE_VERSION: ${{ inputs.release-version }} | ||
| REPORT: ${{ inputs.report }} | ||
| OUTPUT: ${{ inputs.output }} | ||
| REPO: ${{ inputs.repo }} | ||
| OWNER: ${{ inputs.owner }} | ||
| GITHUB_TOKEN: ${{ inputs.github-token }} | ||
| run: | | ||
| if [ -n "$RELEASE_VERSION" ] && [ -n "$REPORT" ]; then | ||
| echo "::error::Only one of 'release-version' or 'report' may be provided" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$RELEASE_VERSION" ] && [ -z "$REPORT" ]; then | ||
| echo "::error::Either 'release-version' or 'report' must be provided" | ||
| exit 1 | ||
| fi | ||
|
|
||
| docker_args=(--rm -v "${PWD}:/github/workspace" -w /github/workspace) | ||
| bundle_args=(changelog bundle --config "$CONFIG" --resolve --output "$OUTPUT") | ||
|
|
||
| if [ -n "$RELEASE_VERSION" ]; then | ||
| bundle_args+=(--release-version "$RELEASE_VERSION") | ||
| docker_args+=(-e GITHUB_TOKEN) | ||
| if [ -n "$REPO" ]; then bundle_args+=(--repo "$REPO"); fi | ||
| if [ -n "$OWNER" ]; then bundle_args+=(--owner "$OWNER"); fi | ||
| fi | ||
|
|
||
| if [ -n "$REPORT" ]; then | ||
| if [[ "$REPORT" == https://* ]]; then | ||
| curl -fsSL "$REPORT" -o .bundle-report.html | ||
| REPORT=".bundle-report.html" | ||
| elif [[ "$REPORT" == http://* ]]; then | ||
| echo "::error::Report URL must use HTTPS: ${REPORT}" | ||
| exit 1 | ||
| fi | ||
| bundle_args+=(--report "$REPORT") | ||
| docker_args+=(--network none) | ||
| fi | ||
|
|
||
| docker run "${docker_args[@]}" ghcr.io/elastic/docs-builder:edge "${bundle_args[@]}" | ||
|
|
||
| - name: Upload bundle artifact | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: ${{ inputs.artifact-name }} | ||
| path: ${{ inputs.output }} | ||
| if-no-files-found: error | ||
| retention-days: 1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <!-- Generated by https://github.com/reakaleek/gh-action-readme --> | ||
| # <!--name-->changelog/bundle-pr<!--/name--> | ||
| <!--description--> | ||
| Downloads a changelog bundle artifact and opens a pull request to add it to the repository. If a PR already exists for the same bundle, it is updated in place. | ||
| <!--/description--> | ||
|
|
||
| ## Inputs | ||
| <!--inputs--> | ||
| | Name | Description | Required | Default | | ||
| |----------------|----------------------------------------------------------------------------------------------------------------------|----------|-----------------------| | ||
| | `output` | Output file path for the bundle, relative to the repo root (e.g. docs/releases/v9.2.0.yaml). Must match the bundle-create action. | `true` | | | ||
| | `github-token` | GitHub token with contents:write and pull-requests:write permissions | `false` | `${{ github.token }}` | | ||
| <!--/inputs--> | ||
|
|
||
| ## Outputs | ||
| <!--outputs--> | ||
| | Name | Description | | ||
| |------|-------------| | ||
| <!--/outputs--> | ||
|
|
||
| ## Usage | ||
| <!--usage action="elastic/docs-actions/changelog/bundle-pr" version="v1"--> | ||
| ```yaml | ||
| steps: | ||
| - uses: elastic/docs-actions/changelog/bundle-pr@v1 | ||
| with: | ||
| output: docs/releases/v9.2.0.yaml | ||
| ``` | ||
| <!--/usage--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is a reusable workflow necessary if it has only one step?
it would be necessary, if we split it into 2 jobs (https://github.com/elastic/docs-actions/pull/42/changes#r2997494919)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I've split them with their specific permissions now.