Skip to content

Commit 8c4cbc7

Browse files
authored
Optimize preview build permissions (#1526)
* Optimize preview build permissions * Fix deadlock * Fix conditions * Make 'match' a dependency of 'check' job
1 parent 5968556 commit 8c4cbc7

File tree

1 file changed

+169
-85
lines changed

1 file changed

+169
-85
lines changed

.github/workflows/preview-build.yml

Lines changed: 169 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,24 @@ 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:
6468
match:
6569
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') }}
6970
runs-on: ubuntu-latest
71+
permissions:
72+
contents: none
73+
deployments: none
74+
pull-requests: none
75+
id-token: none
7076
outputs:
7177
content-source-match: ${{ steps.event-check.outputs.content-source-match != '' && steps.event-check.outputs.content-source-match || steps.match.outputs.content-source-match }}
7278
content-source-next: ${{ steps.event-check.outputs.content-source-next != '' && steps.event-check.outputs.content-source-next || steps.match.outputs.content-source-next }}
@@ -99,45 +105,69 @@ jobs:
99105
echo "ref=${{ github.ref_name }}"
100106
echo "repo=${{ github.repository }}"
101107
102-
build:
103-
if: github.event.repository.fork == false # Skip running the job on the fork itself (It still runs on PRs on the upstream from forks)
104-
concurrency:
105-
group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref || github.ref }}
106-
cancel-in-progress: ${{ startsWith(github.event_name, 'pull_request') }}
108+
check:
107109
runs-on: ubuntu-latest
108-
env:
109-
GITHUB_PR_REF_NAME: ${{ github.event.pull_request.head.ref }}
110-
MATCH: ${{ needs.match.outputs.content-source-match }}
111-
needs: [ match ]
110+
needs:
111+
- match
112+
permissions:
113+
contents: read
114+
deployments: none
115+
id-token: none
116+
pull-requests: read
117+
outputs:
118+
any_modified: ${{ steps.check-files.outputs.any_modified }}
119+
all_changed_files: ${{ steps.check-files.outputs.all_changed_files }}
112120
steps:
113-
114121
- name: Checkout
115-
if: env.MATCH == 'true' && (contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name))
122+
if: contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name)
116123
uses: actions/checkout@v4
117124
with:
118125
ref: ${{ github.event.pull_request.head.sha || github.ref }}
119126

120127
- name: Get changed files
121-
if: env.MATCH == 'true' && (contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name))
128+
if: contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name)
122129
id: check-files
123130
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
124131
with:
125132
files: ${{ inputs.path-pattern != '' && inputs.path-pattern || '**' }}
126-
files_ignore: ${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }}
127-
133+
files_ignore: |
134+
${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }}
135+
.github/**
136+
README.md
137+
138+
build:
139+
if: github.event.repository.fork == false # Skip running the job on the fork itself (It still runs on PRs on the upstream from forks)
140+
runs-on: ubuntu-latest
141+
permissions:
142+
contents: read
143+
deployments: write
144+
id-token: write
145+
pull-requests: none
146+
outputs:
147+
deployment_result: ${{ steps.deployment.outputs.result }}
148+
env:
149+
GITHUB_PR_REF_NAME: ${{ github.event.pull_request.head.ref }}
150+
MATCH: ${{ needs.match.outputs.content-source-match }}
151+
needs:
152+
- check
153+
- match
154+
steps:
128155
- name: Checkout
129-
if: env.MATCH == 'true' && (startsWith(github.event_name, 'pull_request') && steps.check-files.outputs.any_modified == 'true')
156+
if: >
157+
env.MATCH == 'true'
158+
&& needs.check.outputs.any_modified == 'true'
130159
uses: actions/checkout@v4
131160
with:
132161
ref: ${{ github.event.pull_request.head.sha || github.ref }}
133162
persist-credentials: false
134163

135164
- 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-
)
165+
if: >
166+
env.MATCH == 'true'
167+
&& (
168+
contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
169+
|| (needs.check.outputs.any_modified == 'true' && startsWith(github.event_name, 'pull_request'))
170+
)
141171
uses: actions/github-script@v7
142172
id: deployment
143173
env:
@@ -170,7 +200,9 @@ jobs:
170200
return deployment.data.id
171201
172202
- name: Generate env.PATH_PREFIX
173-
if: env.MATCH == 'true' && (steps.deployment.outputs.result)
203+
if: >
204+
env.MATCH == 'true'
205+
&& steps.deployment.outputs.result
174206
env:
175207
PR_NUMBER: ${{ github.event.pull_request.number }}
176208
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -189,22 +221,35 @@ jobs:
189221
esac
190222
191223
- name: Bootstrap Action Workspace
192-
if: env.MATCH == 'true' && (github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
224+
if: >
225+
env.MATCH == 'true'
226+
&& github.repository == 'elastic/docs-builder'
227+
&& steps.deployment.outputs.result
193228
uses: elastic/docs-builder/.github/actions/bootstrap@main
194229

195230
# we run our artifact directly, please use the prebuild
196231
# elastic/docs-builder@main GitHub Action for all other repositories!
197232
- name: Build documentation
198-
if: env.MATCH == 'true' && (github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
233+
if: >
234+
env.MATCH == 'true'
235+
&& github.repository == 'elastic/docs-builder'
236+
&& steps.deployment.outputs.result
199237
run: |
200238
dotnet run --project src/tooling/docs-builder -- --strict --path-prefix "${PATH_PREFIX}"
201239
202240
- 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'))
241+
if: >
242+
env.MATCH == 'true'
243+
&& (
244+
github.repository != 'elastic/docs-builder'
245+
&& (
246+
steps.deployment.outputs.result
247+
|| (
248+
needs.check.outputs.any_modified == 'true'
249+
&& github.event_name == 'merge_group'
250+
)
207251
)
252+
)
208253
uses: elastic/docs-builder@main
209254
id: docs-build
210255
continue-on-error: ${{ fromJSON(inputs.continue-on-error != '' && inputs.continue-on-error || 'false') }}
@@ -214,68 +259,136 @@ jobs:
214259
metadata-only: ${{ fromJSON(inputs.metadata-only != '' && inputs.metadata-only || 'false') }}
215260

216261
- 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'))
262+
if: >
263+
env.MATCH == 'true'
264+
&& (
265+
!cancelled()
266+
&& steps.docs-build.outputs.skip != 'true'
267+
&& (
268+
steps.deployment.outputs.result
269+
|| (
270+
needs.check.outputs.any_modified == 'true'
271+
&& github.event_name == 'merge_group'
272+
)
273+
)
221274
)
222275
uses: elastic/docs-builder/actions/validate-inbound-local@main
223276

224277
- 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'))
278+
if: >
279+
env.MATCH == 'true'
280+
&& (
281+
!cancelled()
282+
&& steps.docs-build.outputs.skip != 'true'
283+
&& (
284+
steps.deployment.outputs.result
285+
|| (
286+
needs.check.outputs.any_modified == 'true'
287+
&& github.event_name == 'merge_group'
288+
)
289+
)
229290
)
230291
uses: elastic/docs-builder/actions/validate-path-prefixes-local@main
231292

232293
- uses: elastic/docs-builder/.github/actions/aws-auth@main
233-
if: ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result }}
234-
294+
if: >
295+
!cancelled()
296+
&& steps.docs-build.outputs.skip != 'true'
297+
&& steps.deployment.outputs.result
235298
- name: Upload to S3
236299
id: s3-upload
237-
if: |
238-
env.MATCH == 'true' &&
239-
(!cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result)
300+
if: >
301+
env.MATCH == 'true'
302+
&& !cancelled()
303+
&& steps.docs-build.outputs.skip != 'true'
304+
&& steps.deployment.outputs.result
240305
run: |
241306
aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview${PATH_PREFIX}" --delete --no-follow-symlinks
242307
aws cloudfront create-invalidation \
243308
--distribution-id EKT7LT5PM8RKS \
244309
--paths "${PATH_PREFIX}" "${PATH_PREFIX}/*"
245-
310+
311+
- name: Update Link Index
312+
if: >
313+
env.MATCH == 'true'
314+
&& (
315+
contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name)
316+
&& (
317+
needs.match.outputs.content-source-current == 'true'
318+
|| needs.match.outputs.content-source-next == 'true'
319+
|| needs.match.outputs.content-source-speculative == 'true'
320+
)
321+
&& steps.s3-upload.outcome == 'success'
322+
)
323+
uses: elastic/docs-builder/actions/update-link-index@main
324+
325+
- name: Update deployment status
326+
uses: actions/github-script@v7
327+
if: >
328+
env.MATCH == 'true'
329+
&& always()
330+
&& steps.deployment.outputs.result
331+
env:
332+
PR_NUMBER: ${{ github.event.pull_request.number }}
333+
LANDING_PAGE_PATH: ${{ steps.docs-build.outputs.landing-page-path || env.PATH_PREFIX }}
334+
with:
335+
script: |
336+
await github.rest.repos.createDeploymentStatus({
337+
owner: context.repo.owner,
338+
repo: context.repo.repo,
339+
deployment_id: ${{ steps.deployment.outputs.result }},
340+
state: "${{ steps.docs-build.outputs.skip == 'true' && 'inactive' || (steps.s3-upload.outcome == 'success' && 'success' || 'failure') }}",
341+
environment_url: `https://docs-v3-preview.elastic.dev${process.env.LANDING_PAGE_PATH}`,
342+
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
343+
})
344+
comment:
345+
if: >
346+
startsWith(github.event_name, 'pull_request')
347+
&& inputs.disable-comments != 'true'
348+
&& needs.build.outputs.deployment_result
349+
&& needs.check.outputs.any_modified
350+
runs-on: ubuntu-latest
351+
needs:
352+
- check
353+
- build
354+
permissions:
355+
contents: none
356+
deployments: none
357+
id-token: none
358+
pull-requests: write
359+
steps:
246360
- name: Comment on PR
247361
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
249362
uses: actions/github-script@v7
250363
env:
251-
ALL_CHANGED_FILES: ${{ steps.check-files.outputs.all_changed_files }}
364+
ALL_CHANGED_FILES: ${{ needs.check.outputs.all_changed_files }}
252365
with:
253366
script: |
254367
const title = '## 🔍 Preview links for changed docs'
255368
const changedMdFiles = process.env.ALL_CHANGED_FILES
256369
.split(/\s+/)
257370
.filter(i => i.endsWith('.md'))
258371
.filter(i => !i.includes('/_snippets/'));
259-
372+
260373
if (changedMdFiles.length === 0) {
261374
return;
262375
}
263-
376+
264377
const toLink = (file) => {
265378
const path = file
266379
.replace('docs/', '')
267380
.replace('/index.md', '')
268381
.replace('.md', '');
269382
return `[${file}](https://docs-v3-preview.elastic.dev${process.env.PATH_PREFIX}/${path})`;
270383
}
271-
384+
272385
const links = changedMdFiles.map(toLink)
273-
386+
274387
const body = [
275388
title,
276389
...links.slice(0, 10).map(i => `- ${i}`),
277390
]
278-
391+
279392
if (links.length > 10) {
280393
body.push('<details>');
281394
body.push('<summary>More links …</summary>');
@@ -286,16 +399,16 @@ jobs:
286399
body.push('');
287400
body.push('</details>');
288401
}
289-
402+
290403
if (links.length > 100) {
291404
body.push('');
292405
body.push(`<sub>In total, ${links.length} files changed.</sub>`);
293406
}
294-
407+
295408
const owner = context.repo.owner;
296409
const repo = context.repo.repo;
297410
const issue_number = context.payload.pull_request.number;
298-
411+
299412
// Post or update a single bot comment
300413
const { data: comments } = await github.rest.issues.listComments({
301414
owner, repo, issue_number
@@ -317,32 +430,3 @@ jobs:
317430
body:body.join('\n'),
318431
});
319432
}
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)