ci: sync tests/README.md to docs (#3164)

This commit is contained in:
Viktor Scharf
2026-07-22 14:27:50 +02:00
committed by GitHub
parent a3a271aad5
commit 44ae3a8ab5
4 changed files with 160 additions and 2 deletions

3
.gitignore vendored
View File

@@ -43,6 +43,9 @@ tests/acceptance/filesForUpload/filesWithVirus/
# QA activity reports
tests/qa-activity-report/reports/
# Generated docs page (published to the server-testing-docs branch by CI)
tests/.docs-dist/
# drone CI is in .drone.star, do not let someone accidentally commit a local .drone.yml
.drone.yml

View File

@@ -610,7 +610,7 @@ def main(ctx):
),
)
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx), optional = True))
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + serverTestingDocs(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx), optional = True))
pipelineSanityChecks(pipelines)
return savePipelineNumber(ctx) + pipelines
@@ -2343,6 +2343,52 @@ def genDocsPr(ctx):
],
}]
def serverTestingDocs(ctx):
return [{
"name": "server-testing-docs",
"steps": [
{
"name": "build",
"image": OC_CI_NODEJS,
"commands": [
"node tests/scripts/generate-docs.mjs",
# add dummy woodpecker config to disable CI on push to the docs branch
"printf 'def main(ctx):\n return [{\n \"name\":\"dummy-pipeline\",\n" +
" \"steps\":[{\"name\":\"dummy-step\",\"image\":\"alpine:latest\"}],\n" +
" \"when\":[{\"branch\":[\"main\"]}],\n }]\n' > tests/.docs-dist/.woodpecker.star",
],
},
{
"name": "publish",
"image": "plugins/gh-pages:1",
"settings": {
"username": {
"from_secret": "github_username",
},
"password": {
"from_secret": "github_token",
},
"pages_directory": "tests/.docs-dist/",
"copy_contents": True,
"target_branch": "server-testing-docs",
"delete": True,
},
"when": [
{
"event": ["push"],
"branch": "${CI_REPO_DEFAULT_BRANCH}",
"path": "tests/README.md",
},
],
},
],
"when": [
{
"event": ["push", "pull_request"],
},
],
}]
def notifyMatrixCheckSteps(ctx, depends_on):
result = [{
"name": "all-checks-finished",

View File

@@ -174,7 +174,7 @@ TEST_GROUP=BaseWopiViewing docker compose -f tests/acceptance/docker/src/wopi-va
Use the arm image for macOS to run the validator tests.
```bash
WOPI_VALIDATOR_IMAGE=scharfvi/wopi-validator \
WOPI_VALIDATOR_IMAGE=opencloudeu/wopi-validator \
TEST_GROUP=BaseWopiViewing \
docker compose -f tests/acceptance/docker/src/wopi-validator-test.yml up -d
```

View File

@@ -0,0 +1,109 @@
// Transforms tests/README.md into a Docusaurus-ready markdown page and writes
// it to tests/.docs-dist/. CI publishes that directory to the
// `server-testing-docs` branch, which the docs site (opencloud-eu/docs) pulls
// into docs/dev/server/testing via git-batch (.batchfile).
//
// Run locally with: node tests/scripts/generate-docs.mjs
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const HERE = path.dirname(fileURLToPath(import.meta.url))
const TESTS_DIR = path.resolve(HERE, '..')
const REPO_ROOT = path.resolve(TESTS_DIR, '..')
const INPUT = path.join(TESTS_DIR, 'README.md')
const OUT_DIR = path.join(TESTS_DIR, '.docs-dist')
// tests, relative to the repo root, used to resolve README-relative links.
const TESTS_REL = path.relative(REPO_ROOT, TESTS_DIR).split(path.sep).join('/')
const GH_BLOB = 'https://github.com/opencloud-eu/opencloud/blob/main'
const FRONT_MATTER = `---
title: 'Acceptance Testing'
sidebar_position: 1
id: acceptance-testing
---
`
const CATEGORY = {
label: 'Testing',
position: 4
}
// GitHub alert syntax -> Docusaurus admonitions.
const ALERT_TYPES = {
NOTE: 'note',
TIP: 'tip',
IMPORTANT: 'info',
WARNING: 'warning',
CAUTION: 'danger'
}
function stripTitleAndToc(md) {
// Docusaurus renders the title from front matter, so drop the leading H1.
md = md.replace(/^#\s+.*\r?\n+/, '')
// Drop the hand-maintained "Table of Contents" section (auto-generated by Docusaurus).
md = md.replace(/^##\s+Table of Contents\s*\r?\n[\s\S]*?(?=^##\s)/m, '')
return md
}
function stripHugoShortcodes(md) {
// Hugo shortcodes ({{< ref "x" >}}) are not valid in Docusaurus MDX and raw
// "{{ }}" would break the build. Keep the link text, drop the broken target.
md = md.replace(/\[([^\]]+)\]\(\s*\{\{[<%][\s\S]*?[%>]\}\}\s*\)/g, '$1')
// Remove any remaining bare shortcodes.
md = md.replace(/\{\{[<%][\s\S]*?[%>]\}\}/g, '')
return md
}
function convertAlerts(md) {
const lines = md.split('\n')
const out = []
for (let i = 0; i < lines.length; i++) {
const match = lines[i].match(/^>\s*\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*$/)
if (!match) {
out.push(lines[i])
continue
}
const type = ALERT_TYPES[match[1]]
const body = []
while (i + 1 < lines.length && lines[i + 1].startsWith('>')) {
i++
body.push(lines[i].replace(/^>\s?/, ''))
}
out.push(`:::${type}`, ...body, ':::')
}
return out.join('\n')
}
function rewriteRelativeLinks(md) {
// ](./foo) or ](../foo) -> absolute GitHub blob URL, resolved against tests/.
return md.replace(/\]\((\.{1,2}\/[^)]+)\)/g, (_full, rel) => {
const repoRelative = path.posix.join(TESTS_REL, rel)
return `](${GH_BLOB}/${repoRelative})`
})
}
async function main() {
const readme = await readFile(INPUT, 'utf8')
const body = rewriteRelativeLinks(
convertAlerts(stripHugoShortcodes(stripTitleAndToc(readme)))
)
const page = `${FRONT_MATTER}\n${body.replace(/^\n+/, '')}`
if (page.includes('{{')) {
console.warn('Warning: unresolved "{{" remains in the output; Docusaurus MDX may fail.')
}
await rm(OUT_DIR, { recursive: true, force: true })
await mkdir(OUT_DIR, { recursive: true })
await writeFile(path.join(OUT_DIR, 'index.md'), page, 'utf8')
await writeFile(path.join(OUT_DIR, '_category_.json'), JSON.stringify(CATEGORY, null, 2) + '\n', 'utf8')
console.log(`Wrote ${path.relative(REPO_ROOT, OUT_DIR)}/{index.md,_category_.json}`)
}
main().catch((err) => {
console.error(err)
process.exit(1)
})