11name : preview-build
22
33on :
4- pull_request_target :
4+ pull_request :
55 types :
66 - opened
77 - synchronize
1010 branches :
1111 - main
1212 - master
13+ # TODO remove these need to be added to individual repositories
14+ - ' \d+.\d+.\d+'
15+ - ' \d+.\d+'
16+ - ' \d+.x'
17+ tags :
18+ - ' v?\d+.\d+.\d+'
19+ - ' v?\d+.\d+'
1320 workflow_call :
1421 inputs :
1522 strict :
3138 type : string
3239 default : ' **'
3340 required : false
41+ path-pattern-ignore :
42+ description : ' Path pattern to ignore files.'
43+ type : string
44+ default : ' '
45+ required : false
3446 free-disk-space :
3547 description : ' Free disk space before running the build'
3648 type : string
3749 default : ' false'
3850 required : false
51+ disable-comments :
52+ description : ' Disable comments'
53+ type : boolean
54+ default : false
55+ required : false
3956
4057permissions :
4158 id-token : write
4259 deployments : write
4360 contents : read
44- pull-requests : read
61+ pull-requests : write
4562
4663jobs :
64+ match :
65+ 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') }}
69+ runs-on : ubuntu-latest
70+ outputs :
71+ content-source-match : ${{ steps.event-check.outputs.content-source-match != '' && steps.event-check.outputs.content-source-match || steps.match.outputs.content-source-match }}
72+ content-source-next : ${{ steps.event-check.outputs.content-source-next != '' && steps.event-check.outputs.content-source-next || steps.match.outputs.content-source-next }}
73+ content-source-current : ${{ steps.event-check.outputs.content-source-current != '' && steps.event-check.outputs.content-source-current || steps.match.outputs.content-source-current }}
74+ content-source-speculative : ${{ steps.event-check.outputs.content-source-speculative != '' && steps.event-check.outputs.content-source-speculative || steps.match.outputs.content-source-speculative }}
75+ steps :
76+ - name : Not a push event
77+ id : event-check
78+ if : contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name)
79+ # we always want to run for pull requests, but we do not want to indicate its either content source
80+ run : |
81+ echo "content-source-match=true" >> $GITHUB_OUTPUT
82+ echo "content-source-next=false" >> $GITHUB_OUTPUT
83+ echo "content-source-current=false" >> $GITHUB_OUTPUT
84+ echo "content-source-speculative=false" >> $GITHUB_OUTPUT
85+ - name : Match for push events
86+ id : match
87+ if : contains(fromJSON('["push"]'), github.event_name)
88+ uses : elastic/docs-builder/actions/assembler-match@main
89+ with :
90+ ref_name : ${{ github.ref_name }}
91+ repository : ${{ github.repository }}
92+ - name : Debug
93+ run : |
94+ echo "Non sensitive data, echo'ing here temporarily to validate this job before connecting it further into the build job"
95+ echo "content-source-match=${{ steps.event-check.outputs.content-source-match != '' && steps.event-check.outputs.content-source-match || steps.match.outputs.content-source-match }}"
96+ echo "content-source-next=${{ steps.event-check.outputs.content-source-next != '' && steps.event-check.outputs.content-source-next || steps.match.outputs.content-source-next }}"
97+ echo "content-source-current=${{ steps.event-check.outputs.content-source-current != '' && steps.event-check.outputs.content-source-current || steps.match.outputs.content-source-current }}"
98+ echo "content-source-speculative=${{ steps.event-check.outputs.content-source-speculative != '' && steps.event-check.outputs.content-source-speculative || steps.match.outputs.content-source-speculative }}"
99+ echo "ref=${{ github.ref_name }}"
100+ echo "repo=${{ github.repository }}"
101+
47102 build :
48103 if : github.event.repository.fork == false # Skip running the job on the fork itself (It still runs on PRs on the upstream from forks)
49104 concurrency :
@@ -52,30 +107,37 @@ jobs:
52107 runs-on : ubuntu-latest
53108 env :
54109 GITHUB_PR_REF_NAME : ${{ github.event.pull_request.head.ref }}
110+ MATCH : ${{ needs.match.outputs.content-source-match }}
111+ needs : [ match ]
55112 steps :
56113
57114 - name : Checkout
58- if : contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name)
115+ if : env.MATCH == 'true' && ( contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name) )
59116 uses : actions/checkout@v4
60117 with :
61118 ref : ${{ github.event.pull_request.head.sha || github.ref }}
62119
63120 - name : Get changed files
64- if : contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name)
121+ if : env.MATCH == 'true' && ( contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name) )
65122 id : check-files
66123 uses : tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
67124 with :
68125 files : ${{ inputs.path-pattern != '' && inputs.path-pattern || '**' }}
126+ files_ignore : ${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }}
69127
70128 - name : Checkout
71- if : startsWith(github.event_name, 'pull_request') && steps.check-files.outputs.any_modified == 'true'
129+ if : env.MATCH == 'true' && ( startsWith(github.event_name, 'pull_request') && steps.check-files.outputs.any_modified == 'true')
72130 uses : actions/checkout@v4
73131 with :
74132 ref : ${{ github.event.pull_request.head.sha || github.ref }}
75133 persist-credentials : false
76134
77135 - name : Create Deployment
78- if : contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name) || (steps.check-files.outputs.any_modified == 'true' && startsWith(github.event_name, 'pull_request'))
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+ )
79141 uses : actions/github-script@v7
80142 id : deployment
81143 env :
@@ -108,7 +170,7 @@ jobs:
108170 return deployment.data.id
109171
110172 - name : Generate env.PATH_PREFIX
111- if : steps.deployment.outputs.result
173+ if : env.MATCH == 'true' && ( steps.deployment.outputs.result)
112174 env :
113175 PR_NUMBER : ${{ github.event.pull_request.number }}
114176 GITHUB_REF_NAME : ${{ github.ref_name }}
@@ -119,10 +181,6 @@ jobs:
119181 ;;
120182 "push" | "workflow_dispatch")
121183 echo "PATH_PREFIX=/${GITHUB_REPOSITORY}/tree/${GITHUB_REF_NAME}" >> $GITHUB_ENV
122- if [[ ! "${GITHUB_REF_NAME}" =~ ^(main|master|16\.x)$ ]]; then
123- echo "Unsupported ref name: '${GITHUB_REF_NAME}'";
124- exit 1;
125- fi
126184 ;;
127185 *)
128186 echo "Unsupported event: '${GITHUB_EVENT_NAME}'";
@@ -131,53 +189,150 @@ jobs:
131189 esac
132190
133191 - name : Bootstrap Action Workspace
134- if : github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result
192+ if : env.MATCH == 'true' && ( github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
135193 uses : elastic/docs-builder/.github/actions/bootstrap@main
136194
137- # we run our artifact directly please use the prebuild
195+ # we run our artifact directly, please use the prebuild
138196 # elastic/docs-builder@main GitHub Action for all other repositories!
139197 - name : Build documentation
140- if : github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result
198+ if : env.MATCH == 'true' && ( github.repository == 'elastic/docs-builder' && steps.deployment.outputs.result)
141199 run : |
142200 dotnet run --project src/tooling/docs-builder -- --strict --path-prefix "${PATH_PREFIX}"
143201
144202 - name : Build documentation
145- if : github.repository != 'elastic/docs-builder' && (steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group'))
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'))
207+ )
146208 uses : elastic/docs-builder@main
147209 id : docs-build
148210 continue-on-error : ${{ fromJSON(inputs.continue-on-error != '' && inputs.continue-on-error || 'false') }}
149211 with :
150212 prefix : ${{ env.PATH_PREFIX }}
151213 strict : ${{ fromJSON(inputs.strict != '' && inputs.strict || 'true') }}
152- metadata-only : ${{ fromJSON(inputs.metadata-only != '' && inputs.metadata-only || 'true ') }}
214+ metadata-only : ${{ fromJSON(inputs.metadata-only != '' && inputs.metadata-only || 'false ') }}
153215
154216 - name : ' Validate inbound links'
155- if : ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && (steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group')) }}
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'))
221+ )
156222 uses : elastic/docs-builder/actions/validate-inbound-local@main
157223
158224 - name : ' Validate local path prefixes against those claimed by global navigation.yml'
159- if : ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && (steps.deployment.outputs.result || (steps.check-files.outputs.any_modified == 'true' && github.event_name == 'merge_group')) }}
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'))
229+ )
160230 uses : elastic/docs-builder/actions/validate-path-prefixes-local@main
161231
162232 - uses : elastic/docs-builder/.github/actions/aws-auth@main
163233 if : ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result }}
164234
165235 - name : Upload to S3
166236 id : s3-upload
167- if : ${{ !cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result }}
237+ if : |
238+ env.MATCH == 'true' &&
239+ (!cancelled() && steps.docs-build.outputs.skip != 'true' && steps.deployment.outputs.result)
168240 run : |
169241 aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview${PATH_PREFIX}" --delete --no-follow-symlinks
170242 aws cloudfront create-invalidation \
171243 --distribution-id EKT7LT5PM8RKS \
172244 --paths "${PATH_PREFIX}" "${PATH_PREFIX}/*"
245+
246+ - name : Comment on PR
247+ 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
249+ uses : actions/github-script@v7
250+ env :
251+ ALL_CHANGED_FILES : ${{ steps.check-files.outputs.all_changed_files }}
252+ with :
253+ script : |
254+ const title = '## 🔍 Preview links for changed docs'
255+ const changedMdFiles = process.env.ALL_CHANGED_FILES
256+ .split(/\s+/)
257+ .filter(i => i.endsWith('.md'))
258+ .filter(i => !i.includes('/_snippets/'));
259+
260+ if (changedMdFiles.length === 0) {
261+ return;
262+ }
263+
264+ const toLink = (file) => {
265+ const path = file
266+ .replace('docs/', '')
267+ .replace('/index.md', '')
268+ .replace('.md', '');
269+ return `[${file}](https://docs-v3-preview.elastic.dev${process.env.PATH_PREFIX}/${path})`;
270+ }
271+
272+ const links = changedMdFiles.map(toLink)
273+
274+ const body = [
275+ title,
276+ ...links.slice(0, 10).map(i => `- ${i}`),
277+ ]
278+
279+ if (links.length > 10) {
280+ body.push('<details>');
281+ body.push('<summary>More links …</summary>');
282+ body.push('');
283+ for (const link of links.slice(10, 100)) {
284+ body.push(`- ${link}`);
285+ }
286+ body.push('');
287+ body.push('</details>');
288+ }
289+
290+ if (links.length > 100) {
291+ body.push('');
292+ body.push(`<sub>In total, ${links.length} files changed.</sub>`);
293+ }
294+
295+ const owner = context.repo.owner;
296+ const repo = context.repo.repo;
297+ const issue_number = context.payload.pull_request.number;
298+
299+ // Post or update a single bot comment
300+ const { data: comments } = await github.rest.issues.listComments({
301+ owner, repo, issue_number
302+ });
303+ const existing = comments.find(c =>
304+ c.user.type === 'Bot' &&
305+ c.body.startsWith(title)
306+ );
307+ if (existing) {
308+ await github.rest.issues.updateComment({
309+ owner, repo,
310+ comment_id: existing.id,
311+ body: body.join('\n'),
312+ });
313+ } else {
314+ await github.rest.issues.createComment({
315+ owner, repo,
316+ issue_number,
317+ body:body.join('\n'),
318+ });
319+ }
173320
174321 - name : Update Link Index
175- if : contains(fromJSON('["push", "workflow_dispatch"]'), github.event_name) && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') && steps.s3-upload.outcome == 'success'
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')
176331 uses : elastic/docs-builder/actions/update-link-index@main
177332
178333 - name : Update deployment status
179334 uses : actions/github-script@v7
180- if : always() && steps.deployment.outputs.result
335+ if : env.MATCH == 'true' && ( always() && steps.deployment.outputs.result)
181336 env :
182337 PR_NUMBER : ${{ github.event.pull_request.number }}
183338 LANDING_PAGE_PATH : ${{ steps.docs-build.outputs.landing-page-path || env.PATH_PREFIX }}
0 commit comments