Files
mattermost/.github/workflows/docs-ci.yaml
Eva SarafianouandCursor c57df45d9c docs: self-host fonts, images, and OpenAPI icons; block build egress (#39092)
* docs: self-host fonts, images, and OpenAPI icons; block build egress

Stop hotlinking GitHub/user-images and Google Fonts on the docs site, replace
embedded video iframes with links, and fail CI when a build would fetch
off-origin resources (closed allowlist for the security-updates feed).

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: address CodeRabbit egress review findings

Scan an offline (no-Algolia) rebuild in Docs CI, tighten ATTR/getAttr
boundaries, flag remote template-literal prefixes before ${, and add
alt text for the self-hosted plugin-management image.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: replace egress fixture tree with in-memory unit tests

Keep scanner coverage without committing dozens of tiny HTML/CSS/JS
fixture files. scanSources takes string maps; CLI smoke uses a temp dir.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: keep YouTube/Wistia embeds on hosted site

Restore in-page players for the public docs. Allowlist those hosts in
check-egress; the offline packager strips them for airgap.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: simplify hosted-embed allowlist to base domains

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: tighten hosted-embed allowlist to player kinds and paths

Only iframe/script/img player URLs pass; fetch() and other loads to
YouTube/Wistia hosts still fail egress.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: allow Wistia swatch preload in hosted-embed egress check

The organize-conversations embed emits link[rel=preload] for the
swatch; kind-scoped allowlisting missed it and failed Docs CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: use getAttr boundary for script hasSrc check

\b matches inside data-src, so the old hasSrc could skip scanning an
inline script body. Align with ATTR/getAttr and cover the case in tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 17:58:54 +03:00

73 lines
1.9 KiB
YAML

name: Docs CI
on:
pull_request:
paths:
- "docs/**"
- "api/v4/source/**"
- "api/playbooks/**"
push:
branches:
- master
paths:
- "docs/**"
- "api/v4/source/**"
- "api/playbooks/**"
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
persist-credentials: false
- name: Set up Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: docs/site/.nvmrc
cache: "npm"
cache-dependency-path: docs/site/package-lock.json
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version-file: api/server/go.mod
- name: Install docs dependencies
working-directory: docs/site
run: npm ci
- name: Typecheck
working-directory: docs/site
run: npm run typecheck
- name: Egress-check unit tests
working-directory: docs/site
run: npm run test:egress
- name: Build docs site (includes OpenAPI prebuild)
working-directory: docs/site
run: npm run build
env:
ALGOLIA_APP_ID: ${{ vars.ALGOLIA_APP_ID }}
ALGOLIA_SEARCH_API_KEY: ${{ vars.ALGOLIA_SEARCH_API_KEY }}
# Hosted Algolia injects SearchBar preconnects; do not scan that artifact.
# Rebuild without ALGOLIA_* (prebuild already ran) for the offline shape.
- name: Rebuild without Algolia for egress scan
working-directory: docs/site
run: npx docusaurus build && npm run postbuild
env:
BASE_URL: /
- name: Scan built site for egress
working-directory: docs/site
run: npm run check:egress