Browse Source

configure Antora and CI workflow to support partial build (single version)

- upgrade to Antora 3.2.0-alpha.2
- upgrade release-line-extension to 1.0.0-alpha.2
- add atlas-extension
- add local autoconfig-partial-build extension
- configure deploy-docs.yml workflow to detect and set up partial build
- configure publish-docs.sh script to sync partial build
Dan Allen 2 năm trước cách đây
mục cha
commit
7491f8a76d

+ 8 - 1
.github/actions/publish-docs.sh

@@ -1,5 +1,6 @@
 #!/bin/bash
 
+FROM=build/site
 HOST="$1"
 HOST_PATH="$2"
 SSH_PRIVATE_KEY="$3"
@@ -13,10 +14,16 @@ fi
 
 (
   set -e
+  set -f
   install -m 600 -D /dev/null "$SSH_PRIVATE_KEY_PATH"
   echo "$SSH_PRIVATE_KEY" > "$SSH_PRIVATE_KEY_PATH"
   echo "$SSH_KNOWN_HOST" > ~/.ssh/known_hosts
-  rsync --delete -avze "ssh -i $SSH_PRIVATE_KEY_PATH" build/site/ "$HOST:$HOST_PATH"
+  RSYNC_OPTS='-avz --delete'
+  if [ -n "$BUILD_REFNAME" ]; then
+    RSYNC_OPTS="-n $RSYNC_OPTS$(find $FROM -mindepth 1 -maxdepth 1 \! -name 404.html \! -name '.*' -type f -printf ' --include /%P')"
+    RSYNC_OPTS="$RSYNC_OPTS$(find $FROM -mindepth 1 -maxdepth 1 -type d \! -name _ -printf ' --include /%P --include /%P/**') --exclude **"
+  fi
+  rsync $RSYNC_OPTS -e "ssh -i $SSH_PRIVATE_KEY_PATH" $FROM/ "$HOST:$HOST_PATH"
 )
 exit_code=$?
 

+ 11 - 1
.github/workflows/deploy-docs.yml

@@ -1,6 +1,10 @@
 name: Deploy Docs
 on:
   workflow_dispatch:
+    inputs:
+      build-refname:
+        description: Enter git refname to build (e.g., 5.7.x).
+        required: false
   push:
     branches: docs-build
 permissions: read-all
@@ -10,7 +14,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - name: Checkout
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
         fetch-depth: 5
     - name: Set Up Gradle
@@ -24,6 +28,12 @@ jobs:
       run: |
         rm -f /home/runner/.gradle/caches/modules-2/modules-2.lock
         rm -f /home/runner/.gradle/caches/modules-2/gc.properties
+    - name: Set up refname build
+      if: github.event.inputs.build-refname
+      run: |
+        git fetch --depth 1 https://github.com/$GITHUB_REPOSITORY ${{ github.event.inputs.build-refname }}
+        echo BUILD_REFNAME=${{ github.event.inputs.build-refname }} >> $GITHUB_ENV
+        echo BUILD_VERSION=$(git cat-file --textconv FETCH_HEAD:gradle.properties | sed -n '/^version=/ { s/^version=//;p }') >> $GITHUB_ENV
     - name: Run Antora
       run: ./gradlew antora
     - name: Publish Docs

+ 2 - 0
antora-playbook.yml

@@ -1,8 +1,10 @@
 antora:
   extensions:
+  - ./lib/antora/extensions/autoconfig-partial-build.js
   - ./lib/antora/extensions/inject-collector-config.js
   - '@antora/collector-extension'
   - ./lib/antora/extensions/version-fix.js
+  - '@antora/atlas-extension'
   - '@opendevise/antora-release-line-extension'
 site:
   title: Spring Security

+ 3 - 2
build.gradle

@@ -4,7 +4,7 @@ plugins {
 }
 
 antora {
-    version = '3.2.0-alpha.1'
+    version = '3.2.0-alpha.2'
 	options = ['--clean', '--fetch', '--stacktrace']
 	environment = [
 		'ALGOLIA_API_KEY': '82c7ead946afbac3cf98c32446154691',
@@ -12,7 +12,8 @@ antora {
 		'ALGOLIA_INDEX_NAME': 'security-docs'
     ]
 	dependencies = [
+		'@antora/atlas-extension': '1.0.0-alpha.1',
 		'@antora/collector-extension': '1.0.0-alpha.2',
-		'@opendevise/antora-release-line-extension': '1.0.0-alpha.1'
+		'@opendevise/antora-release-line-extension': '1.0.0-alpha.2'
 	]
 }

+ 55 - 0
lib/antora/extensions/autoconfig-partial-build.js

@@ -0,0 +1,55 @@
+'use strict'
+
+const execFile = require('node:util').promisify(require('node:child_process').execFile)
+const { promises: fsp } = require('node:fs')
+
+module.exports.register = function () {
+  if (!process.env.BUILD_REFNAME) return
+
+  this.once('playbookBuilt', async ({ playbook }) => {
+    const { concat: get } = this.require('simple-get')
+    const asciidocAttrs = ((playbook.asciidoc ||= {}).attributes ||= {})
+    const siteManifestUrl = asciidocAttrs['primary-site-manifest-url'] || `${playbook.site.url}/site-manifest.json`
+    const siteManifestData = await (siteManifestUrl.startsWith('https://')
+      ? download(get, siteManifestUrl)
+      : fsp.readFile(siteManifestUrl)
+    ).then(JSON.parse)
+    let { BUILD_REFNAME: refname, BUILD_VERSION: version } = process.env
+    const isBranch = /[a-z]$/.test(refname)
+    if (!version) {
+      const repoUrl = await execFile('git', ['remote', 'get-url', 'origin']).then(({ stdout: output }) => output.trim())
+      const propertiesUrl = `${repoUrl.replace('github.com', 'raw.githubusercontent.com')}/${refname}/gradle.properties`
+      version = await download(get, propertiesUrl)
+        .then((contents) => contents.toString().split('\n').find((it) => it.startsWith('version='))?.slice(8))
+    }
+    if (isBranch && version.endsWith('-SNAPSHOT')) version = version.slice(0, -9)
+    const versionsInManifest = siteManifestData.components.ROOT.versions
+    if (!(version in versionsInManifest && isBranch === !!versionsInManifest[version].prerelease)) {
+      const category = require('path').basename(module.id, '.js')
+      this.getLogger(category).info(`version ${version} not previously built; reverting to full build`)
+      return
+    }
+    Object.assign(
+      playbook.content.sources[0],
+      isBranch ? { branches: [refname], tags: [] } : { branches: [], tags: [refname] }
+    )
+    Object.assign(
+      asciidocAttrs,
+      { 'primary-site-url': '.', 'primary-site-manifest-url': siteManifestUrl }
+    )
+    this.updateVariables({ playbook })
+  })
+}
+
+function download (get, url) {
+  return new Promise((resolve, reject) =>
+    get({ url }, (err, response, contents) => {
+      if (err) reject(err)
+      if (response.statusCode !== 200) {
+        const message = `Response code ${response.statusCode} (${response.statusMessage})`
+        return reject(Object.assign(new Error(message), { name: 'HTTPError' }))
+      }
+      resolve(contents)
+    })
+  )
+}