개발
더 많은 작업
이 문서는 Wikven에 작업하고자 하는 사람들을 위해 Wikven이 어떻게 만들어지는지 설명합니다. Wikven은 위키텍스트 디렉터리를 정적 웹사이트로 바꿔 주는 MediaWiki 확장 기능과 소수의 관리 스크립트로 이루어져 있습니다. 새로운 렌더링 엔진을 더하는 것이 아니라, MediaWiki 자체를 구동한 다음 그 결과물을 갈무리합니다.
구조
Wikven 빌드는 네 개의 구성 요소로 이루어집니다:
- 확장 기능(
extension.json,includes/). Wikven의 설정과, MediaWiki의 출력을 정적 호스트에 맞게 조정하는 몇 가지 훅을 등록합니다. 편집/역사 UI와 사이드바의 위키 전용 링크를 숨기고, 푸터 링크를 설정된WikvenFooterUrl/WikvenEditUrl/WikvenHistoryUrl로 바꾸며, 내부 URL이index.php?title=대신.html파일을 가리키도록 다시 씁니다. - 관리 스크립트(
maintenance/). 아래에서 설명하는 빌드 파이프라인입니다. WikvenSettings.php. 빌드가 그 아래에서 실행되는LocalSettings.php입니다. 설정을 불러오고, 이미지 백엔드를 감지하며, Wikven의 기본값을 적용합니다.bin/entrypoint스크립트와Dockerfile. MediaWiki 1.46과 확장 기능을, 기본 명령이 빌드 한 번을 실행하는 이미지로 패키징합니다.
이미지 빌드하기
docker build --tag wikven .
Dockerfile은 FROM mediawiki:1.46입니다. Composer와 unzip(서드파티 확장 기능을 가져올 때 필요)을 추가하고, 확장 기능을 /var/www/html/extensions/Wikven으로 복사하며, WikvenSettings.php를 MediaWiki 루트로 복사하고, bin/entrypoint 스크립트를 이미지의 기본 명령(CMD)으로 설정합니다.
빌드 실행하기
docker run --rm \
-v "$(pwd)/docs:/workspace/src" \
-v "$(pwd)/dist:/workspace/dist" \
wikven
컨테이너는 소스를 /workspace/src에 마운트하고 렌더링된 사이트를 /workspace/dist에 기록합니다. 두 경로 모두 WIKVEN_WORKDIR(기본값 /workspace)에서 파생되며, 여기에는 일시적 상태를 위한 .cache/도 있습니다. 이 동일한 배치 덕분에 단독 실행 바이너리는 모든 것을 쓰기 가능한 호스트 디렉터리로 향하게 할 수 있습니다.
run 스크립트는:
- 일회용 MediaWiki를 SQLite 데이터베이스에 설치하고(웹 서버 없음. 만들어지는 관리자 계정은 결코 사용되지 않습니다),
- 서드파티 확장 기능과 스킨을 가져오며(아래 참고),
- 생성된
LocalSettings.php에require_once 'WikvenSettings.php';를 덧붙이고, - 빌드 파이프라인을 실행한 다음,
- 파일 캐시가 내보내는 문서별 역사를 삭제합니다.
빌드 파이프라인
maintenance/build.php는 단계마다 부트스트랩 비용을 치르는 대신 MediaWiki를 한 번만 부팅하고 모든 단계를 자식 관리 스크립트로 실행합니다. 순서대로:
setMainPageMediaWiki:Mainpage를 가져온index문서로 지정하여, 사이트 루트가index.html로 해석되도록 합니다.importImages- 소스 디렉터리의 이미지 파일을
File:네임스페이스로 업로드합니다. 위키텍스트 가져오기 전에 실행되므로, 로컬 이미지를 삽입한 문서가 깨진 미디어 자리표시자 대신 실제 섬네일을 렌더링합니다. importWikitext- 모든
*.wikitext파일을 가져옵니다(하위 디렉터리까지 재귀하므로Template:Foo/styles.css같은 문서는 중첩된 파일일 수 있습니다).File:설명 문서와MediaWiki:시스템 문서는 편집 훅이 발동하도록 현재 판으로 저장되고, 일반 문서는 옛 판으로 가져옵니다. 각 문서에는 그 원본 파일을 마지막으로 바꾼 커밋의 시각이 찍히고 그 커밋의 작성자가 편집자로 기록되므로, 푸터의 "마지막 편집" 줄이 그 줄에서 이어지는 역사의 첫 항목과 맞아떨어집니다. 저장소의 역사에 닿을 수 없다면 — 얕은 체크아웃이거나, 소스 디렉터리가 체크아웃 안에 있지 않은 경우 — 모든 문서는 빌드 중인 커밋의 시각으로 찍히고 편집자는 표시되지 않습니다. RunJobs- MediaWiki의 작업 큐를 실행하며, 주로 섬네일 생성과 링크 테이블 갱신입니다.
RebuildFileCache- 모든 콘텐츠 문서를
dist/아래의 HTML 파일로 렌더링합니다. 이것은 MediaWiki 자체의 파일 캐시입니다. Wikven은File:도 콘텐츠 네임스페이스로 취급하므로, 모든 틀을 덤프하지 않고도 파일 설명 문서가 내보내집니다. buildStyles- 문서가 참조하는 각 CSS 모듈을 로컬 파일로 다시 렌더링하고,
site.styles모듈(MediaWiki:Common.css와 스킨의 사이트 CSS)을 별도 파일로 렌더링합니다. buildScripts- 문서에 필요한 JavaScript를 두 파일로 덤프합니다.
startup-static.js(네트워크 자동 로드를 제거한 로더 매니페스트)와modules-static.js(전체 의존성 폐포로, 모든 모듈이 스스로 실행됨)입니다.site모듈(MediaWiki:Common.js와 스킨의 JS)과, 실제 위키가 암묵적으로 끌어오는 기본 소도구를 심어 둡니다. rewriteScripts- 캐시된 HTML이
load.php대신 로컬 번들을 불러오도록 다시 씁니다. 비동기 startup 태그를 정적 파일과 명시적인mw.loader.load()로 바꾸고, 사이트 스타일을 마지막에 링크해 캐스케이드에서 이기게 하며, SifterSearch가 정적 색인을 제공하지 않는 한 실제 API가 필요한 검색 상자를 제거합니다. storeImages- 참조된 모든 이미지(InstantCommons를 통한 위키미디어 공용, 또는 로컬 업로드)를 콘텐츠 해시된 로컬 파일로 복사하고 URL을 다시 써서, 열람 시점에 네트워크로 아무것도 가져오지 않도록 합니다.
rename- 네임스페이스 접두사가 붙은 캐시 파일에 읽기 쉬운 이름을 부여합니다(예:
ns6%3A...가File:...이 됨).
설정
설정은 계층으로 이루어집니다. default.yml은 Wikven의 기본 MediaWiki 설정을 제공하고, 사이트의 .wikven.yaml이 그 위에 병합됩니다. WikvenSettings.php는 둘 다를 MediaWiki 자체의 YAML 설정 파서로 읽어, 병합된 config 맵을 적용하고, 나열된 extensions와 skins를 불러오며, $wgLogos를 업로드된 WikvenLogos 파일로 향하게 합니다. 또한 실행 시점에 섬네일 백엔드를 감지하는데, 가능하면 ImageMagick과 rsvg를, 그렇지 않으면 내장 GD 라이브러리와 네이티브 인라인 SVG를 사용하므로, 동일한 빌드가 이미지에서도 GD만 있는 바이너리에서도 동작합니다.
이 단계들이 존재하는 이유
실제로 구동 중인 위키는 load.php, 액션 API, 데이터베이스에 의존하지만, 정적 호스트에는 이 중 무엇도 없습니다. 각 파이프라인 단계는 그런 의존성을 하나씩 없앱니다. 파일 캐시가 렌더러를 대체하고, buildStyles/buildScripts/rewriteScripts가 load.php를 대체하며, storeImages가 섬네일/공용 엔드포인트를 대체하고, 확장 기능의 훅이 API를 호출할 UI를 제거합니다. 남는 것은 평범한 HTML, CSS, JS, 그리고 이미지입니다.
서드파티 확장 기능과 스킨
extensions/skins에 있는 이름 중 Wikven에 번들되지 않은 것은 빌드 시점에 maintenance/fetchExtensions.php가 WikvenRepositories에 선언된 소스(tarball, Git 저장소, 또는 Composer 패키지)에서 가져옵니다. 이는 설치 후 WikvenSettings.php가 연결되기 전에 실행되므로, MediaWiki가 구성 요소를 불러올 때쯤이면 이미 디스크에 있습니다.
단독 실행 바이너리
동일한 MediaWiki + Wikven 트리가 단일 FrankenPHP 실행 파일로 내장되어(binary.Dockerfile 참고), Docker 없이도 사이트를 빌드할 수 있습니다. 바이너리는 시작 시 자신의 앱을 쓰기 가능한 임시 디렉터리로 추출하고 동일한 파이프라인을 실행하는데, 이것이 모든 쓰기 가능한 경로를 WIKVEN_WORKDIR 아래에 두는 이유입니다.
지속적 통합
lint.yml은 포매터와 린터(Biome, mago, rumdl, taplo, typos, yamllint, zizmor, phpcs)를 실행합니다.docker-image.yml은 이미지를 빌드하고main에서ghcr.io/chaotic-ground/wikven에 게시합니다.deploy-docs.yml은 이미지로docs/디렉터리를 빌드하고 그 결과를 GitHub Pages에 배포하므로, 이 사이트 자체가 하나의 Wikven 빌드입니다.binary.yml은 단독 실행 바이너리를 빌드합니다. 해당 파일을 건드리는 풀 리퀘스트에서, 그리고 릴리스 때는 각 플랫폼용으로 실행됩니다.release-please.yml이 이를 호출하여 버전 릴리스에 바이너리를 첨부하고,nightly.yml이 매일 이를 호출하여 날짜가 붙은nightly-YYYY-MM-DD프리릴리스를 게시합니다. 둘 다 릴리스를 초안으로 만들고, 바이너리를 첨부한 다음 게시하는데, GitHub의 불변 릴리스는 릴리스가 게시되고 나면 자산을 잠그기 때문입니다.
버전은 Conventional Commits를 따르며, release-please가 이를 사용해 변경 로그를 생성하고 버전을 올립니다.