Green up
Tracking docs/openapi.json (so the app can serve the spec at runtime) makes docs/ exist on the published GitHub mirror, which defeated the skipif(not DOCS.is_dir()) guard in the docs publish/version tests: they then ran against a prose-less checkout and failed on CI. Key the skip off docs/*.md prose instead, matching the canonical published-checkout definition in scripts/check-gates-ran.sh. Also: the OpenAPI generator emitted a trailing-slash path (/api/docs/), which a strict proxy like IIS treats as a redirecting resource a subpath-mounted client cannot follow; normalise trailing slashes in _norm_path and correct the committed spec. And allow docx (python-docx) as an undeclared import: it is used only by scripts/docs/generate_docx.py, a developer tool that never runs on a deployed site.
This commit is contained in:
committed by
cproudlock
parent
902339baf9
commit
1fa005eb8a
@@ -20109,7 +20109,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/docs/": {
|
"/api/docs": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"core-docs"
|
"core-docs"
|
||||||
|
|||||||
@@ -59,7 +59,13 @@ def _product_version():
|
|||||||
|
|
||||||
def _norm_path(p):
|
def _norm_path(p):
|
||||||
# Flask <int:id> / <id> -> OpenAPI {id}
|
# Flask <int:id> / <id> -> OpenAPI {id}
|
||||||
return re.sub(r'<(?:[^:>]+:)?([^>]+)>', r'{\1}', p or '')
|
normalised = re.sub(r'<(?:[^:>]+:)?([^>]+)>', r'{\1}', p or '')
|
||||||
|
# A trailing slash in a published path is a distinct resource to a strict
|
||||||
|
# proxy (IIS), which answers the unslashed URL with a redirect a client
|
||||||
|
# behind a subpath mount cannot follow. Emit the canonical, slashless form.
|
||||||
|
if len(normalised) > 1:
|
||||||
|
normalised = normalised.rstrip('/')
|
||||||
|
return normalised
|
||||||
|
|
||||||
|
|
||||||
def _security(auth):
|
def _security(auth):
|
||||||
|
|||||||
@@ -28,9 +28,15 @@ DOCS = REPO / 'docs'
|
|||||||
# test_there_are_docs_to_check exists to catch. Distinguishing the two matters:
|
# test_there_are_docs_to_check exists to catch. Distinguishing the two matters:
|
||||||
# collapsing them either breaks CI on the published mirror (this module failed
|
# collapsing them either breaks CI on the published mirror (this module failed
|
||||||
# there for exactly this reason) or quietly disables the guard everywhere.
|
# there for exactly this reason) or quietly disables the guard everywhere.
|
||||||
|
#
|
||||||
|
# The test is docs/*.md PROSE, not docs/ existing. docs/openapi.json is tracked
|
||||||
|
# so the app can serve it at runtime, which means docs/ exists even on the
|
||||||
|
# published mirror - keying off the directory made this module run there against
|
||||||
|
# a prose-less tree and fail. A published checkout is one with no authored
|
||||||
|
# prose, matching the canonical definition in scripts/check-gates-ran.sh.
|
||||||
pytestmark = pytest.mark.skipif(
|
pytestmark = pytest.mark.skipif(
|
||||||
not DOCS.is_dir(),
|
not any(DOCS.glob('*.md')),
|
||||||
reason='no docs/ in this checkout - it is excluded from publication and lives in the wiki')
|
reason='no docs/ prose in this checkout - it is excluded from publication and lives in the wiki')
|
||||||
|
|
||||||
# Kept in step with the scrub list in tools/export-github.sh. Two mechanisms for
|
# Kept in step with the scrub list in tools/export-github.sh. Two mechanisms for
|
||||||
# one rule is not ideal, but the export scrubs a tree it is about to commit while
|
# one rule is not ideal, but the export scrubs a tree it is about to commit while
|
||||||
|
|||||||
@@ -23,9 +23,14 @@ import pytest
|
|||||||
REPO = Path(__file__).resolve().parents[1]
|
REPO = Path(__file__).resolve().parents[1]
|
||||||
DOCS = REPO / 'docs'
|
DOCS = REPO / 'docs'
|
||||||
|
|
||||||
|
# docs/openapi.json is tracked so the app can serve it at runtime, so docs/
|
||||||
|
# exists even on the published mirror where the authored prose is not. Keying
|
||||||
|
# the skip off the directory made this module run on the mirror against a
|
||||||
|
# prose-less tree and fail. A published checkout is one with no docs/*.md prose,
|
||||||
|
# matching the canonical definition in scripts/check-gates-ran.sh.
|
||||||
pytestmark = pytest.mark.skipif(
|
pytestmark = pytest.mark.skipif(
|
||||||
not DOCS.is_dir(),
|
not any(DOCS.glob('*.md')),
|
||||||
reason='no docs/ in this checkout - it is excluded from publication')
|
reason='no docs/ prose in this checkout - it is excluded from publication')
|
||||||
|
|
||||||
# The map is generated and the changelog records history; both are allowed to
|
# The map is generated and the changelog records history; both are allowed to
|
||||||
# carry literal versions. CONTRACT-STABILITY's table is a history of what each
|
# carry literal versions. CONTRACT-STABILITY's table is a history of what each
|
||||||
|
|||||||
@@ -38,6 +38,13 @@ ALLOWED_UNDECLARED = {
|
|||||||
'pip',
|
'pip',
|
||||||
'setuptools',
|
'setuptools',
|
||||||
'pkg_resources',
|
'pkg_resources',
|
||||||
|
# python-docx, used ONLY by scripts/docs/generate_docx.py to turn local
|
||||||
|
# authored Markdown into DOCX deliverables in exports/. That script is a
|
||||||
|
# developer convenience: the app never imports it, no deployed site runs it,
|
||||||
|
# and the Markdown it reads is itself gitignored. Declaring it in the
|
||||||
|
# production requirements would ship a doc-generation library to every
|
||||||
|
# customer venv for no runtime purpose.
|
||||||
|
'docx',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user