Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/main-push-ui-bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
- name: Install dependencies
run: yarn workspaces foreach --all install
- name: Check cache
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/offline-bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc

- name: Install dependencies
run: yarn workspaces foreach --all install
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
package-manager-cache: false
- name: Check if PR only changes draft blog posts
id: check
run: |
Expand Down Expand Up @@ -75,6 +80,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
- name: Install dependencies
run: yarn workspaces foreach --all install
- name: Check cache
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
- name: Download pull request artifact
uses: actions/github-script@v7
with:
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14
22
893 changes: 0 additions & 893 deletions .yarn/releases/yarn-4.1.0.cjs

This file was deleted.

1,000 changes: 1,000 additions & 0 deletions .yarn/releases/yarn-4.18.0.cjs

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
approvedGitRepositories: []

compressionLevel: mixed

enableGlobalCache: true

enableScripts: true

nodeLinker: node-modules

npmMinimalAgeGate: 4320

plugins:
- path: github-release-binary.js

yarnPath: .yarn/releases/yarn-4.1.0.cjs
yarnPath: .yarn/releases/yarn-4.18.0.cjs
7 changes: 5 additions & 2 deletions antora-playbook-snippets/antora-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,13 @@ antora:
version: '*'
local-mappings: ac-mappings.yml

- require: '@djencks/asciidoctor-jsonpath'
# NOTE these two are required via local wrappers rather than directly; see
# extensions/asciidoctor-jsonpath.js for why (Antora 3.1.9+ register-signature warning
# combined with runtime.log.failure_level: warn).
- require: ./extensions/asciidoctor-jsonpath.js
# log_level: trace

- require: '@djencks/asciidoctor-antora-indexer'
- require: ./extensions/asciidoctor-antora-indexer.js
# log_level: debug
requires: 'util=camel-website-util'
index_pages:
Expand Down
100 changes: 53 additions & 47 deletions antora-ui-camel/gulp.d/tasks/build-preview-pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,69 +10,73 @@ const asciidoctor = require('@asciidoctor/core')()
const data = require('gulp-data')
const fs = require('fs-extra')
const handlebars = require('handlebars')
const { obj: map } = require('through2')
const merge = require('merge-stream')
const { objectTransform: map } = require('through2')
const ordered = require('ordered-read-streams')
const ospath = require('path')
const path = ospath.posix
const requireFromString = require('require-from-string')
const { Writable } = require('stream')
const { pipeline } = require('stream/promises')
const template = require('gulp-template')
const vfs = require('vinyl-fs')
const yaml = require('js-yaml')

const ASCIIDOC_ATTRIBUTES = { experimental: '', icons: 'font', sectanchors: '', 'source-highlighter': 'highlight.js' }

module.exports = (src, previewSrc, previewDest, sink = () => map()) => (done) =>
Promise.all([
module.exports = (src, previewSrc, previewDest, sink = () => map()) => async () => {
const [baseUiModel, { layouts }] = await Promise.all([
loadSampleUiModel(previewSrc),
toPromise(
merge(
ordered([
compileLayouts(src),
registerPartials(src),
registerHelpers(src),
registerTemplatedHelpers(src),
copyImages(previewSrc, previewDest)
)
copyImages(previewSrc, previewDest),
])
),
])
.then(([baseUiModel, { layouts }]) => [{ ...baseUiModel, env: process.env }, layouts])
.then(([baseUiModel, layouts]) =>
vfs
.src('**/*.adoc', { base: previewSrc, cwd: previewSrc })
.pipe(
map((file, enc, next) => {
const siteRootPath = path.relative(ospath.dirname(file.path), ospath.resolve(previewSrc))
const uiModel = { ...baseUiModel }
uiModel.page = { ...uiModel.page }
uiModel.siteRootPath = siteRootPath
uiModel.siteRootUrl = path.join(siteRootPath, 'index.html')
uiModel.uiRootPath = path.join(siteRootPath, '_')
if (file.stem === '404') {
uiModel.page = { layout: '404', title: 'Page Not Found' }
} else {
const doc = asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
uiModel.page.attributes = Object.entries(doc.getAttributes())
.filter(([name, val]) => name.startsWith('page-'))
.reduce((accum, [name, val]) => {
accum[name.substr(5)] = val
return accum
}, {})
uiModel.page.layout = doc.getAttribute('page-layout', 'default')
uiModel.page.title = doc.getDocumentTitle()
uiModel.page.contents = Buffer.from(doc.convert())
}
file.extname = '.html'
try {
file.contents = Buffer.from(layouts.get(uiModel.page.layout)(uiModel))
next(null, file)
} catch (e) {
next(transformHandlebarsError(e, uiModel.page.layout))
}
})
)
.pipe(vfs.dest(previewDest))
.on('error', (e) => done)
.pipe(sink())
)

const renderPages = map((file, enc, next) => {
const siteRootPath = path.relative(ospath.dirname(file.path), ospath.resolve(previewSrc))
const uiModel = { ...baseUiModel, env: process.env }
uiModel.page = { ...uiModel.page }
uiModel.siteRootPath = siteRootPath
uiModel.siteRootUrl = path.join(siteRootPath, 'index.html')
uiModel.uiRootPath = path.join(siteRootPath, '_')
if (file.stem === '404') {
uiModel.page = { layout: '404', title: 'Page Not Found' }
} else {
const doc = asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
uiModel.page.attributes = Object.entries(doc.getAttributes())
.filter(([name, val]) => name.startsWith('page-'))
.reduce((accum, [name, val]) => {
accum[name.substr(5)] = val
return accum
}, {})
uiModel.page.layout = doc.getAttribute('page-layout', 'default')
uiModel.page.title = doc.getDocumentTitle()
uiModel.page.contents = Buffer.from(doc.convert())
}
file.extname = '.html'
try {
file.contents = Buffer.from(layouts.get(uiModel.page.layout)(uiModel))
next(null, file)
} catch (e) {
next(transformHandlebarsError(e, uiModel.page.layout))
}
})

// NOTE gulp 5 settles async tasks on their returned promise, so wait for the final
// preview output stream (and optional live-reload sink) to drain before completing.
await pipeline(
vfs.src('**/*.adoc', { base: previewSrc, cwd: previewSrc }),
renderPages,
vfs.dest(previewDest),
sink(),
new Writable({ objectMode: true, write: (file, enc, next) => next() })
)
}

function loadSampleUiModel (src) {
return fs.readFile(ospath.join(src, 'ui-model.yml'), 'utf8').then((contents) => yaml.load(contents))
Expand Down Expand Up @@ -151,11 +155,13 @@ function transformHandlebarsError ({ message, stack }, layout) {
return err
}

// NOTE resolves on 'end' rather than 'finish': ordered-read-streams returns a streamx
// readable, which has no writable side to emit 'finish'.
function toPromise (stream) {
return new Promise((resolve, reject, data = {}) =>
stream
.on('error', reject)
.on('data', (chunk) => chunk.constructor === Object && Object.assign(data, chunk))
.on('finish', () => resolve(data))
.on('end', () => resolve(data))
)
}
69 changes: 53 additions & 16 deletions antora-ui-camel/gulp.d/tasks/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const concat = require('gulp-concat')
const cssnano = require('cssnano')
const data = require('gulp-data')
const fs = require('fs-extra')
const merge = require('merge-stream')
const ordered = require('ordered-read-streams')
const ospath = require('path')
const path = ospath.posix
const postcss = require('gulp-postcss')
Expand All @@ -21,22 +21,50 @@ const rewrite = require('gulp-rev-rewrite')
const template = require('gulp-template')
const terser = require('gulp-terser')
const vfs = require('vinyl-fs')
const { obj: map } = require('through2')
const { Writable } = require('stream')
const { pipeline } = require('stream/promises')
const { objectTransform: map } = require('through2')

module.exports = (src, dest, preview) => async () => {
const opts = { base: src, cwd: src }
const sourcemaps = preview || process.env.SOURCEMAPS === 'true'
const postcssPlugins = [
postcssImport,
(css, { messages, opts: { file } }) =>
Promise.all(
// NOTE these are PostCSS 8 visitor plugins; the bare `(css, result) => ...` form these
// used to take is the PostCSS 7 API and is no longer invoked.
const trackImportMtimes = {
postcssPlugin: 'camel-track-import-mtimes',
OnceExit (css, { result }) {
const { messages, opts: { file } } = result
return Promise.all(
messages
.reduce((accum, { file: depPath, type }) => (type === 'dependency' ? accum.concat(depPath) : accum), [])
.map((importedPath) => fs.stat(importedPath).then(({ mtime }) => mtime))
).then((mtimes) => {
const newestMtime = mtimes.reduce((max, curr) => (!max || curr > max ? curr : max), file.stat.mtime)
if (newestMtime > file.stat.mtime) file.stat.mtimeMs = +(file.stat.mtime = newestMtime)
}),
})
},
}

const pseudoElementFixer = {
postcssPlugin: 'camel-pseudo-element-fixer',
OnceExit: (css) => postcssPseudoElementFixer(css),
}

// NOTE postcss-custom-properties substitutes var() in real declarations but, unlike the
// postcss 7 release, keeps the :root block that defines them. Once preserve is false
// nothing reads those definitions any more, and the oldest browserslist targets (ie 11,
// op_mini) ignore custom properties outright, so drop them rather than ship dead bytes.
const dropResolvedCustomProperties = {
postcssPlugin: 'camel-drop-resolved-custom-properties',
OnceExit (css) {
css.walkDecls(/^--/, (decl) => decl.remove())
css.walkRules((rule) => rule.nodes.length || rule.remove())
},
}

const postcssPlugins = [
postcssImport,
trackImportMtimes,
postcssUrl([
{
filter: '**/*.@(woff|woff2)',
Expand All @@ -51,18 +79,18 @@ module.exports = (src, dest, preview) => async () => {
},
]),
postcssVar({ preserve: preview }),
preview ? postcssCalc : () => {},
...(preview ? [postcssCalc()] : [dropResolvedCustomProperties]),
autoprefixer,
preview
? () => {}
: (css, result) => cssnano({ preset: 'default' })(css, result).then(() => postcssPseudoElementFixer(css, result)),
...(preview ? [] : [cssnano({ preset: 'default' }), pseudoElementFixer]),
]

const imagemin = await import('gulp-imagemin')

let manifest

return merge(
// NOTE merge-stream is a node-core PassThrough and silently drops files from the streamx
// streams vinyl-fs 4 produces; ordered-read-streams is the streamx-native equivalent.
const staged = ordered([
vfs
.src('js/+([0-9])-*.js', { ...opts, sourcemaps })
.pipe(terser())
Expand Down Expand Up @@ -108,9 +136,11 @@ module.exports = (src, dest, preview) => async () => {
.src('css/site.css', { ...opts, sourcemaps })
.pipe(postcss((file) => ({ plugins: postcssPlugins, options: { file } })))
.pipe(rev()),
vfs.src('font/*.{ttf,woff*(2)}', opts),
// NOTE fonts are not staged from src; the postcssUrl handler above copies them straight
// into dest/font from their npm packages, and vinyl-fs 4 errors on a missing src/font.
// NOTE gulp 5 decodes contents as UTF-8 by default, which would corrupt binary assets
vfs
.src('img/**/*.{jpg,ico,png,svg}', opts)
.src('img/**/*.{jpg,ico,png,svg}', { ...opts, encoding: false })
.pipe(
imagemin.default([
imagemin.gifsicle(),
Expand All @@ -129,8 +159,8 @@ module.exports = (src, dest, preview) => async () => {
.pipe(rev()),
vfs.src('helpers/*.js', opts),
vfs.src('layouts/*.hbs', opts),
vfs.src('partials/*.hbs', opts)
)
vfs.src('partials/*.hbs', opts),
])
.pipe(rewrite())
.pipe(vfs.dest(dest, { sourcemaps: sourcemaps && '.' }))
.pipe(rev.manifest())
Expand All @@ -150,6 +180,13 @@ module.exports = (src, dest, preview) => async () => {
})
)
.pipe(vfs.dest(dest))

// NOTE gulp settles an async task on its promise, and a stream is not a thenable, so the
// pipeline must be awaited here or bundle:pack packs a partly written dest into
// ui-bundle.zip. The sink consumes what the final vfs.dest re-emits so the pipeline keeps
// draining instead of stalling once its object buffer fills. pipeline() is used over
// finished() so a failure in any stage rejects rather than hanging the task.
await pipeline(staged, new Writable({ objectMode: true, write: (file, enc, next) => next() }))
}

function postcssPseudoElementFixer (css, result) {
Expand Down
3 changes: 2 additions & 1 deletion antora-ui-camel/gulp.d/tasks/pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const path = require('path')

module.exports = (src, dest, bundleName, onFinish) => () =>
vfs
.src('**/*', { base: src, cwd: src })
// NOTE encoding: false keeps fonts and images byte-exact; gulp 5 would otherwise decode as UTF-8
.src('**/*', { base: src, cwd: src, encoding: false })
.pipe(zip.dest(path.join(dest, `${bundleName}-bundle.zip`)))
.on('finish', () => onFinish && onFinish(path.resolve(dest, `${bundleName}-bundle.zip`)))
2 changes: 1 addition & 1 deletion antora-ui-camel/gulp.d/tasks/remove.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const fs = require('fs-extra')
const { obj: map } = require('through2')
const { objectTransform: map } = require('through2')
const vfs = require('vinyl-fs')

module.exports = (files) => () =>
Expand Down
Loading
Loading