Skip to content

Commit eb4b45e

Browse files
committed
Optimize preview build permissions
1 parent 5968556 commit eb4b45e

File tree

1 file changed

+169
-87
lines changed

1 file changed

+169
-87
lines changed

.github/workflows/preview-build.yml

Lines changed: 169 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,49 @@ on:
5555
required: false
5656

5757
permissions:
58-
id-token: write
59-
deployments: write
6058
contents: read
59+
deployments: write
60+
id-token: write
6161
pull-requests: write
62+
63+
concurrency:
64+
group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref || github.ref }}
65+
cancel-in-progress: ${{ startsWith(github.event_name, 'pull_request') }}
6266

6367
jobs:
68+
check:
69+
runs-on: ubuntu-latest
70+
permissions:
71+
contents: read
72+
deployments: none
73+
id-token: none
74+
pull-requests: read
75+
outputs:
76+
any_modified: ${{ steps.check-files.outputs.any_modified }}
77+
all_changed_files: ${{ steps.check-files.outputs.all_changed_files }}
78+
steps:
79+
- name: Checkout
80+
if: contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name)
81+
uses: actions/checkout@v4
82+
with:
83+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
84+
85+
- name: Get changed files
86+
if: contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name)
87+
id: check-files
88+
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
89+
with:
90+
files: ${{ inputs.path-pattern != '' && inputs.path-pattern || '**' }}
91+
files_ignore: ${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }}
92+
6493
match:
6594
if: github.event.repository.fork == false # Skip running the job on the fork itself (It still runs on PRs on the upstream from forks)
66-
concurrency:
67-
group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref || github.ref }}
68-
cancel-in-progress: ${{ startsWith(github.event_name, 'pull_request') }}
6995
runs-on: ubuntu-latest
96+
permissions:
97+
contents: none
98+
deployments: none
99+
pull-requests: none
100+
id-token: none
70101
outputs:
71102
content-source-match: ${{ steps.event-check.outputs.content-source-match != '' && steps.event-check.outputs.content-source-match || steps.match.outputs.content-source-match }}
72103
content-source-next: ${{ steps.event-check.outputs.content-source-next != '' && steps.event-check.outputs.content-source-next || steps.match.outputs.content-source-next }}
@@ -105,39 +136,36 @@ jobs:
105136
group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref || github.ref }}
106137
cancel-in-progress: ${{ startsWith(github.event_name, 'pull_request') }}
107138
runs-on: ubuntu-latest
139+
permissions:
140+
contents: read
141+
deployments: write
142+
id-token: write
143+
pull-requests: none
144+
outputs:
145+
deployment_result: ${{ steps.deployment.outputs.result }}
108146
env:
109147
GITHUB_PR_REF_NAME: ${{ github.event.pull_request.head.ref }}
110148
MATCH: ${{ needs.match.outputs.content-source-match }}
111-
needs: [ match ]
149+
needs:
150+
- check
151+
- match
112152
steps:
113-
114-
- name: Checkout
115-
if: env.MATCH == 'true' && (contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name))
116-
uses: actions/checkout@v4
117-
with:
118-
ref: ${{ github.event.pull_request.head.sha || github.ref }}
119-
120-
- name: Get changed files
121-
if: env.MATCH == 'true' && (contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name))
122-
id: check-files
123-
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
124-
with:
125-
files: ${{ inputs.path-pattern != '' && inputs.path-pattern || '**' }}
126-
files_ignore: ${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }}
127-
128153
- name: Checkout
129-
if: env.MATCH == 'true' && (startsWith(github.event_name, 'pull_request') && steps.check-files.outputs.any_modified == 'true')
154+
if: >
155+
env.MATCH == 'true'
156+
&& needs.check.outputs.any_modified == 'true'
130157
uses: actions/checkout@v4
131158
with:
132159
ref: ${{ github.event.pull_request.head.sha || github.ref }}
133160
persist-credentials: false
134161

135162
- name: Create Deployment
136-
if: |
137-
env.MATCH == 'true' &&
138-
(contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
139-
|| (steps.check-files.outputs.any_modified == 'true' && startsWith(github.event_name, 'pull_request'))
140-
)
163+
if: >
164+
env.MATCH == 'true'
165+
&& (
166+
contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
167+
|| (needs.check.outputs.any_modified == 'true' && startsWith(github.event_name, 'pull_request'))
168+
)
141169
uses: actions/github-script@v7
142170
id: deployment
143171
env:
@@ -170,7 +198,9 @@ jobs:
170198
return deployment.data.id
171199
172200
- name: Generate env.PATH_PREFIX
173-
if: env.MATCH == 'true' && (steps.deployment.outputs.result)
201+
if: >
202+
env.MATCH == 'true'
203+
&& steps.deployment.outputs.result
174204
env:
175205
PR_NUMBER: ${{ github.event.pull_request.number }}
176206
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -189,22 +219,35 @@ jobs:
189219
esac
190220
191221
- name: Bootstrap Action Workspace
192-
if: env.MATCH == 'true' && (github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
222+
if: >
223+
env.MATCH == 'true'
224+
&& github.repository == 'elastic/docs-builder'
225+
&& steps.deployment.outputs.result
193226
uses: elastic/docs-builder/.github/actions/bootstrap@main
194227

195228
# we run our artifact directly, please use the prebuild
196229
# elastic/docs-builder@main GitHub Action for all other repositories!
197230
- name: Build documentation
198-
if: env.MATCH == 'true' && (github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
231+
if: >
232+
env.MATCH == 'true'
233+
&& github.repository == 'elastic/docs-builder'
234+
&& steps.deployment.outputs.result
199235
run: |
200236
dotnet run --project src/tooling/docs-builder -- --strict --path-prefix "${PATH_PREFIX}"
201237
202238
- name: Build documentation
203-
if: |
204-
env.MATCH == 'true' &&
205-
(github.repository != 'elastic/docs-builder' &&
206-
(steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group'))
239+
if: >
240+
env.MATCH == 'true'
241+
&& (
242+
github.repository != 'elastic/docs-builder'
243+
&& (
244+
steps.deployment.outputs.result
245+
|| (
246+
needs.check.outputs.any_modified == 'true'
247+
&& github.event_name == 'merge_group'
248+
)
207249
)
250+
)
208251
uses: elastic/docs-builder@main
209252
id: docs-build
210253
continue-on-error: ${{ fromJSON(inputs.continue-on-error != '' && inputs.continue-on-error || 'false') }}
@@ -214,68 +257,136 @@ jobs:
214257
metadata-only: ${{ fromJSON(inputs.metadata-only != '' && inputs.metadata-only || 'false') }}
215258

216259
- name: 'Validate inbound links'
217-
if: |
218-
env.MATCH == 'true' &&
219-
(!cancelled() && steps.docs-build.outputs.skip != 'true'
220-
&& (steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group'))
260+
if: >
261+
env.MATCH == 'true'
262+
&& (
263+
!cancelled()
264+
&& steps.docs-build.outputs.skip != 'true'
265+
&& (
266+
steps.deployment.outputs.result
267+
|| (
268+
needs.check.outputs.any_modified == 'true'
269+
&& github.event_name == 'merge_group'
270+
)
271+
)
221272
)
222273
uses: elastic/docs-builder/actions/validate-inbound-local@main
223274

224275
- name: 'Validate local path prefixes against those claimed by global navigation.yml'
225-
if: |
226-
env.MATCH == 'true' &&
227-
(!cancelled() && steps.docs-build.outputs.skip != 'true' &&
228-
(steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group'))
276+
if: >
277+
env.MATCH == 'true'
278+
&& (
279+
!cancelled()
280+
&& steps.docs-build.outputs.skip != 'true'
281+
&& (
282+
steps.deployment.outputs.result
283+
|| (
284+
needs.check.outputs.any_modified == 'true'
285+
&& github.event_name == 'merge_group'
286+
)
287+
)
229288
)
230289
uses: elastic/docs-builder/actions/validate-path-prefixes-local@main
231290

232291
- uses: elastic/docs-builder/.github/actions/aws-auth@main
233-
if: ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result }}
234-
292+
if: >
293+
!cancelled()
294+
&& steps.docs-build.outputs.skip != 'true'
295+
&& steps.deployment.outputs.result
235296
- name: Upload to S3
236297
id: s3-upload
237-
if: |
238-
env.MATCH == 'true' &&
239-
(!cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result)
298+
if: >
299+
env.MATCH == 'true'
300+
&& !cancelled()
301+
&& steps.docs-build.outputs.skip != 'true'
302+
&& steps.deployment.outputs.result
240303
run: |
241304
aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview${PATH_PREFIX}" --delete --no-follow-symlinks
242305
aws cloudfront create-invalidation \
243306
--distribution-id EKT7LT5PM8RKS \
244307
--paths "${PATH_PREFIX}" "${PATH_PREFIX}/*"
245-
308+
309+
- name: Update Link Index
310+
if: >
311+
env.MATCH == 'true'
312+
&& (
313+
contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
314+
&& (
315+
needs.match.outputs.content-source-current == 'true'
316+
|| needs.match.outputs.content-source-next == 'true'
317+
|| needs.match.outputs.content-source-speculative == 'true'
318+
)
319+
&& steps.s3-upload.outcome == 'success'
320+
)
321+
uses: elastic/docs-builder/actions/update-link-index@main
322+
323+
- name: Update deployment status
324+
uses: actions/github-script@v7
325+
if: >
326+
env.MATCH == 'true'
327+
&& always()
328+
&& steps.deployment.outputs.result
329+
env:
330+
PR_NUMBER: ${{ github.event.pull_request.number }}
331+
LANDING_PAGE_PATH: ${{ steps.docs-build.outputs.landing-page-path || env.PATH_PREFIX }}
332+
with:
333+
script: |
334+
await github.rest.repos.createDeploymentStatus({
335+
owner: context.repo.owner,
336+
repo: context.repo.repo,
337+
deployment_id: ${{ steps.deployment.outputs.result }},
338+
state: "${{ steps.docs-build.outputs.skip == 'true' && 'inactive' || (steps.s3-upload.outcome == 'success' && 'success' || 'failure') }}",
339+
environment_url: `https://docs-v3-preview.elastic.dev${process.env.LANDING_PAGE_PATH}`,
340+
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
341+
})
342+
comment:
343+
runs-on: ubuntu-latest
344+
needs:
345+
- check
346+
- build
347+
permissions:
348+
contents: none
349+
deployments: none
350+
id-token: none
351+
pull-requests: write
352+
steps:
246353
- name: Comment on PR
247354
continue-on-error: true
248-
if: startsWith(github.event_name, 'pull_request') && inputs.disable-comments != 'true' && env.MATCH == 'true' && steps.deployment.outputs.result && steps.check-files.outputs.all_changed_files
355+
if: >
356+
startsWith(github.event_name, 'pull_request')
357+
&& inputs.disable-comments != 'true'
358+
&& needs.build.outputs.deployment_result
359+
&& needs.check.outputs.all_changed_files
249360
uses: actions/github-script@v7
250361
env:
251-
ALL_CHANGED_FILES: ${{ steps.check-files.outputs.all_changed_files }}
362+
ALL_CHANGED_FILES: ${{ needs.check.outputs.all_changed_files }}
252363
with:
253364
script: |
254365
const title = '## 🔍 Preview links for changed docs'
255366
const changedMdFiles = process.env.ALL_CHANGED_FILES
256367
.split(/\s+/)
257368
.filter(i => i.endsWith('.md'))
258369
.filter(i => !i.includes('/_snippets/'));
259-
370+
260371
if (changedMdFiles.length === 0) {
261372
return;
262373
}
263-
374+
264375
const toLink = (file) => {
265376
const path = file
266377
.replace('docs/', '')
267378
.replace('/index.md', '')
268379
.replace('.md', '');
269380
return `[${file}](https://docs-v3-preview.elastic.dev${process.env.PATH_PREFIX}/${path})`;
270381
}
271-
382+
272383
const links = changedMdFiles.map(toLink)
273-
384+
274385
const body = [
275386
title,
276387
...links.slice(0, 10).map(i => `- ${i}`),
277388
]
278-
389+
279390
if (links.length > 10) {
280391
body.push('<details>');
281392
body.push('<summary>More links …</summary>');
@@ -286,16 +397,16 @@ jobs:
286397
body.push('');
287398
body.push('</details>');
288399
}
289-
400+
290401
if (links.length > 100) {
291402
body.push('');
292403
body.push(`<sub>In total, ${links.length} files changed.</sub>`);
293404
}
294-
405+
295406
const owner = context.repo.owner;
296407
const repo = context.repo.repo;
297408
const issue_number = context.payload.pull_request.number;
298-
409+
299410
// Post or update a single bot comment
300411
const { data: comments } = await github.rest.issues.listComments({
301412
owner, repo, issue_number
@@ -317,32 +428,3 @@ jobs:
317428
body:body.join('\n'),
318429
});
319430
}
320-
321-
- name: Update Link Index
322-
if: |
323-
env.MATCH == 'true' &&
324-
(contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
325-
&& (
326-
needs.match.outputs.content-source-current == 'true'
327-
|| needs.match.outputs.content-source-next == 'true'
328-
|| needs.match.outputs.content-source-speculative == 'true'
329-
)
330-
&& steps.s3-upload.outcome == 'success')
331-
uses: elastic/docs-builder/actions/update-link-index@main
332-
333-
- name: Update deployment status
334-
uses: actions/github-script@v7
335-
if: env.MATCH == 'true' && (always() && steps.deployment.outputs.result)
336-
env:
337-
PR_NUMBER: ${{ github.event.pull_request.number }}
338-
LANDING_PAGE_PATH: ${{ steps.docs-build.outputs.landing-page-path || env.PATH_PREFIX }}
339-
with:
340-
script: |
341-
await github.rest.repos.createDeploymentStatus({
342-
owner: context.repo.owner,
343-
repo: context.repo.repo,
344-
deployment_id: ${{ steps.deployment.outputs.result }},
345-
state: "${{ steps.docs-build.outputs.skip == 'true' && 'inactive' || (steps.s3-upload.outcome == 'success' && 'success' || 'failure') }}",
346-
environment_url: `https://docs-v3-preview.elastic.dev${process.env.LANDING_PAGE_PATH}`,
347-
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
348-
})

0 commit comments

Comments
 (0)