Skip to content

Commit 1b56aa2

Browse files
cottiMpdreamzclaude
authored
Add S3 upload support for changelogs (#43)
* Add S3 upload support for changelogs * Add README * Use js-yaml for path checking. * Add pr-number parameter and tighten workflow-level permissions * Fix IFS, add --no-follow-symlinks * Adjust call * Use docs-builder to upload to S3 * Update .gitignore * Update README * Harden release workflows against tag injection and credential leakage (#45) * Harden release workflows against tag injection and credential leakage Made-with: Cursor * Set workflow-level permissions to {} for least-privilege The job already declares contents: write, so the workflow-level contents: read was redundant. Empty permissions at workflow level ensures no implicit grants. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Adjust call * Adjust inputs and concurrency for upload workflow * Adjust concurrency group * Adjust docs, improve push target pattern * Use the push SHA instead of the merge commit SHA * Update README * Add config input * Set cancel-in-progress * Introduce config input and additional documentation * Update README --------- Co-authored-by: Martijn Laarman <Mpdreamz@gmail.com> Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent 32f8296 commit 1b56aa2

4 files changed

Lines changed: 184 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Changelog upload
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
config:
7+
description: 'Path to changelog.yml configuration file'
8+
type: string
9+
default: 'docs/changelog.yml'
10+
11+
permissions: {}
12+
13+
concurrency:
14+
group: changelog-s3-sync-${{ github.repository }}
15+
cancel-in-progress: false
16+
17+
jobs:
18+
upload:
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: read
22+
id-token: write
23+
steps:
24+
- name: Upload changelog
25+
uses: elastic/docs-actions/changelog/upload@v1
26+
with:
27+
config: ${{ inputs.config }}

changelog/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,60 @@ If a human edits the changelog file directly (i.e., the last commit to the chang
178178
## Output
179179

180180
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.
181+
182+
## Uploading to S3
183+
184+
Changelog files on the default branch can be uploaded to the `elastic-docs-v3-changelog-bundles` S3 bucket under `{product}/changelogs/{filename}.yaml`, preserving the original filename as determined by the repository's `filename` strategy in `changelog.yml`. This makes them available for release bundling workflows.
185+
186+
### 1. Add the upload workflow
187+
188+
**`.github/workflows/changelog-upload.yml`**
189+
190+
```yaml
191+
name: changelog-upload
192+
193+
on:
194+
push:
195+
branches: [main, master]
196+
paths:
197+
- 'docs/changelog/**'
198+
- 'docs/changelog.yml'
199+
200+
permissions: {}
201+
202+
jobs:
203+
upload:
204+
uses: elastic/docs-actions/.github/workflows/changelog-upload.yml@v1
205+
```
206+
207+
The `paths` filter is optional — it avoids running the workflow on pushes that don't touch changelog files. If your changelog directory or config lives elsewhere, adjust the paths accordingly.
208+
209+
If your changelog configuration is not at `docs/changelog.yml`, pass the path explicitly:
210+
211+
```yaml
212+
jobs:
213+
upload:
214+
uses: elastic/docs-actions/.github/workflows/changelog-upload.yml@v1
215+
with:
216+
config: path/to/changelog.yml
217+
```
218+
219+
### 2. Enable OIDC access
220+
221+
The upload workflow authenticates to AWS via GitHub Actions OIDC. Your repository must be listed in the `elastic-docs-v3-changelog-bundles` infrastructure to have an IAM role provisioned. Contact the docs-engineering team to add your repository.
222+
223+
### How it works
224+
225+
On each push to `main` or `master`, the upload workflow:
226+
227+
1. Checks out the pushed commit
228+
2. Sets up `docs-builder` and authenticates with AWS via OIDC
229+
3. Runs `docs-builder changelog upload`, which reads your `changelog.yml`, discovers changelog YAML files in the configured directory, and incrementally uploads them to `{product}/changelogs/{filename}.yaml` in the bucket — only files whose content has changed are transferred
230+
231+
If the changelog directory has no files (for example, because changelog generation was skipped), the command exits silently without error.
232+
233+
The workflow uses a per-repository concurrency group so that rapid successive pushes queue rather than run in parallel. If a run is already in progress when a new push arrives, the in-progress run completes before the next one starts. Since `docs-builder` performs incremental uploads (skipping unchanged objects), re-runs are cheap.
234+
235+
> **Note:** The composite action accepts an `aws-account-id` input (default: the Elastic docs account). Overriding this is only valid when OIDC trust and IAM roles have been provisioned for the target account. In practice, most repositories should use the default.
236+
237+
> **Note:** The `github-token` input defaults to the workflow's `GITHUB_TOKEN`, which is scoped to the job's declared permissions. Do not substitute a broader PAT unless `docs-builder/setup` explicitly requires it.

changelog/upload/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!-- Generated by https://github.com/reakaleek/gh-action-readme -->
2+
# <!--name-->Changelog upload<!--/name-->
3+
<!--description-->
4+
Uploads changelog entries to the elastic-docs-v3-changelog-bundles S3 bucket using docs-builder's incremental upload. Intended to run on push to the default branch (main/master). Only files whose content has changed are transferred.
5+
<!--/description-->
6+
7+
## Inputs
8+
<!--inputs-->
9+
| Name | Description | Required | Default |
10+
|------------------|-------------------------------------------------------------------------------------------------------------|----------|-----------------------|
11+
| `config` | Path to changelog.yml configuration file (repo-relative, no ".." or absolute paths) | `false` | `docs/changelog.yml` |
12+
| `github-token` | GitHub token (used by docs-builder setup). Use the default GITHUB_TOKEN; do not substitute a broader PAT. | `false` | `${{ github.token }}` |
13+
| `aws-account-id` | The AWS account ID. Only override if OIDC trust and IAM roles have been provisioned for the target account. | `false` | `197730964718` |
14+
<!--/inputs-->
15+
16+
## Outputs
17+
<!--outputs-->
18+
| Name | Description |
19+
|------|-------------|
20+
<!--/outputs-->
21+
22+
## Usage
23+
<!--usage action="your/action" version="v1"-->
24+
<!--/usage-->

changelog/upload/action.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Changelog upload
2+
description: >
3+
Uploads changelog entries to the elastic-docs-v3-changelog-bundles S3 bucket
4+
using docs-builder's incremental upload. Intended to run on push to the default
5+
branch (main/master). Only files whose content has changed are transferred.
6+
7+
inputs:
8+
config:
9+
description: 'Path to changelog.yml configuration file (repo-relative, no ".." or absolute paths)'
10+
default: 'docs/changelog.yml'
11+
github-token:
12+
description: 'GitHub token (used by docs-builder setup). Use the default GITHUB_TOKEN; do not substitute a broader PAT.'
13+
default: '${{ github.token }}'
14+
aws-account-id:
15+
description: 'The AWS account ID. Only override if OIDC trust and IAM roles have been provisioned for the target account.'
16+
default: '197730964718'
17+
18+
runs:
19+
using: composite
20+
steps:
21+
- name: Verify push to default branch
22+
shell: bash
23+
env:
24+
REF: ${{ github.ref }}
25+
run: |
26+
if [[ "$REF" != "refs/heads/main" && "$REF" != "refs/heads/master" ]]; then
27+
echo "::error::changelog upload must run on a push to main or master (got $REF)"
28+
exit 1
29+
fi
30+
31+
- name: Validate config path
32+
shell: bash
33+
env:
34+
CONFIG: ${{ inputs.config }}
35+
run: |
36+
if [[ "$CONFIG" == /* ]]; then
37+
echo "::error::config path must be relative, not absolute: ${CONFIG}"
38+
exit 1
39+
fi
40+
if [[ "$CONFIG" == *..* ]]; then
41+
echo "::error::config path must not contain '..': ${CONFIG}"
42+
exit 1
43+
fi
44+
if [[ "$CONFIG" == *$'\n'* || "$CONFIG" == *$'\r'* ]]; then
45+
echo "::error::config path must not contain newlines"
46+
exit 1
47+
fi
48+
49+
- name: Checkout
50+
uses: actions/checkout@v6
51+
with:
52+
ref: ${{ github.sha }}
53+
persist-credentials: false
54+
55+
- name: Setup docs-builder
56+
uses: elastic/docs-actions/docs-builder/setup@v1
57+
with:
58+
version: edge
59+
github-token: ${{ inputs.github-token }}
60+
61+
- name: Authenticate with AWS
62+
uses: elastic/docs-actions/aws/auth@v1
63+
with:
64+
aws_account_id: ${{ inputs.aws-account-id }}
65+
aws_role_name_prefix: elastic-docs-v3-changelog-
66+
67+
- name: Upload changelogs
68+
shell: bash
69+
env:
70+
CONFIG: ${{ inputs.config }}
71+
run: |
72+
docs-builder changelog upload \
73+
--artifact-type changelog \
74+
--target s3 \
75+
--s3-bucket-name elastic-docs-v3-changelog-bundles \
76+
--config "$CONFIG"

0 commit comments

Comments
 (0)