Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ jobs:
- name: PHP CS Fixer
run: castor qa:cs --dry-run

docs:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup Castor
uses: castor-php/setup-castor@2a495b8c91f00be6768ad8a040ba8634c797d386 # v1.1.0

- name: Build the documentation website
run: castor docs:build

zizmor:
name: GitHub Actions security analysis
runs-on: ubuntu-latest
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ permissions: {}

jobs:
build:
name: Build documentation website with MkDocs
name: Build documentation website with Zensical
runs-on: ubuntu-latest
permissions:
contents: read
Expand All @@ -40,13 +40,13 @@ jobs:
# Turn Pages on if it is not already, instead of failing
enablement: true

- name: Build site with mkdocs
- name: Build the documentation website
run: castor docs:build

- name: Upload artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ./tools/mkdocs/site
path: ./tools/doc/site

deploy:
name: Deploy to GitHub Pages
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ multiple applications and services.

## Contributing

The documentation lives in [`doc/`](./doc/) and is built with MkDocs:
The documentation lives in [`doc/`](./doc/) and is built with [Zensical](https://zensical.org/):

```bash
castor docs:serve # http://127.0.0.1:8000, rebuilds on change
castor docs:build # build the static site in tools/mkdocs/site
castor docs:build # build the static site in tools/doc/site
```

Quality tooling for the plugin itself:
Expand Down
2 changes: 1 addition & 1 deletion castor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

defined('CASTOR_USE_CHDIR') || define('CASTOR_USE_CHDIR', false);

import(__DIR__ . '/tools/mkdocs/castor.php');
import(__DIR__ . '/tools/doc/castor.php');

#[AsTask(description: 'Run PHPStan', namespace: 'qa', name: 'phpstan', aliases: ['phpstan'])]
function qa_phpstan(bool $generateBaseline = false): int
Expand Down
3 changes: 2 additions & 1 deletion doc/changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
render_macros: true
title: Changelog
description: What changed in each release of the Castor Docker plugin.
---

{% include-markdown "../CHANGELOG.md" %}
{{ markdown("CHANGELOG.md") }}

<!-- markdownlint-disable-file first-line-h1 -->
2 changes: 1 addition & 1 deletion doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function default_context(): Context
|----------|------|
| `root_domain` | Root domain used by the services exposing a UI (`redis.{root_domain}`, `mailpit.{root_domain}`, …) |
| `registry` | Registry the build cache is pushed to and pulled from |
| `repository` | Repository `castor docker:push` labels the images with, so the registry attaches the packages to it — deduced from `GITHUB_REPOSITORY` or the `origin` remote otherwise, see [`docker:push`](tasks.md#publishing-to-ghcr-io) |
| `repository` | Repository `castor docker:push` labels the images with, so the registry attaches the packages to it — deduced from `GITHUB_REPOSITORY` or the `origin` remote otherwise, see [`docker:push`](tasks.md#publishing-to-ghcrio) |
| `project_name` | Compose project name — wins over the `name:` of `compose.yaml`, see [running two checkouts side by side](#running-two-checkouts-side-by-side) |
| `user_id` | UID the containers run as, defaults to your own |
| `twig_dockerfile_frontend` | Overrides the pinned [twig-dockerfile frontend](going-further/custom-dockerfile.md#pinning-the-frontend) |
Expand Down
3 changes: 2 additions & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
render_macros: true
title: Docker environments for PHP, driven from PHP
description: A Castor plugin that generates your Docker Compose stack and the tasks to drive it — applications, databases, router and HTTPS included.
---
Expand All @@ -17,7 +18,7 @@ description: A Castor plugin that generates your Docker Compose stack and the ta

## 🚀 TL;DR

{% include-markdown "../README.md" start="<!-- start index -->" end="<!-- end index -->" %}
{{ markdown("README.md", start="<!-- start index -->", end="<!-- end index -->") }}

## Want more?

Expand Down
2 changes: 1 addition & 1 deletion doc/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ and its image under `latest` — `--tag` publishes it under another name. A
service listing several caches in its `cache_from` pushes to all of them, and
its image to each registry among them. The
image carries `org.opencontainers.image.source`, which is what
[attaches the package to your repository](#publishing-to-ghcr-io).
[attaches the package to your repository](#publishing-to-ghcrio).

`--dry-run` prints the build plan bake resolved, without running it.

Expand Down
2 changes: 2 additions & 0 deletions tools/mkdocs/.gitignore → tools/doc/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ doc/
example/
site/
overrides/partials/jolicode-footer.html
__pycache__/
__pycache__/
9 changes: 9 additions & 0 deletions tools/doc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3-slim

WORKDIR /doc/

RUN pip install \
zensical \
markdown-callouts

CMD ["zensical", "serve"]
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ layers:
- size: { width: 385, height: 100 }
offset: { x: 50, y: 50 }
background:
image: /mkdocs/doc/assets/logo_CASTOR_line@2x.png
image: /doc/doc/assets/logo_CASTOR_line@2x.png

- size: { width: 1200, height: 10 }
offset: { x: 0, y: 620 }
Expand Down
33 changes: 16 additions & 17 deletions tools/mkdocs/castor.php → tools/doc/castor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
use function Castor\io;
use function Castor\run;

const IMAGE_NAME = 'castor-docker-mkdocs';
const IMAGE_NAME = 'castor-docker-doc';

#[AsTask(description: 'Build the MkDocs Docker image', namespace: 'docs', name: 'image')]
#[AsTask(description: 'Build the documentation Docker image', namespace: 'docs', name: 'image')]
function image(bool $force = false): void
{
if (!$force && has_image()) {
Expand All @@ -24,18 +24,18 @@ function image(bool $force = false): void
return;
}

io()->title('Building the MkDocs Docker image');
io()->title('Building the documentation Docker image');

run(['docker', 'build', '-t', IMAGE_NAME, __DIR__]);
}

#[AsTask(description: 'Fetch the JoliCode theme assets used by the documentation', namespace: 'docs', name: 'assets')]
function assets(): void
{
io()->title('Fetching external assets for the MkDocs documentation');
io()->title('Fetching external assets for the documentation');

http_download(
'https://raw.githubusercontent.com/jolicode/oss-theme/refs/heads/main/MkDocs/extra.css',
'https://raw.githubusercontent.com/jolicode/oss-theme/refs/heads/main/Zensical/extra.css',
root() . '/doc/assets/stylesheets/jolicode.css',
);
http_download(
Expand Down Expand Up @@ -64,9 +64,9 @@ function build(): void
{
assets();

io()->title('Building the MkDocs documentation');
io()->title('Building the documentation');

do_run(['mkdocs', 'build']);
do_run(['zensical', 'build', '--strict']);

io()->success(\sprintf('Documentation built in %s/site.', __DIR__));
}
Expand All @@ -76,11 +76,11 @@ function serve(int $port = 8000): void
{
assets();

io()->title('Serving the MkDocs documentation');
io()->title('Serving the documentation');
io()->writeln(\sprintf(' <info>http://127.0.0.1:%d</info>', $port));

do_run(
['mkdocs', 'serve', '--livereload', '--dev-addr', '0.0.0.0:8000'],
['zensical', 'serve', '--dev-addr', '0.0.0.0:8000'],
ports: [\sprintf('%d:8000', $port)],
);
}
Expand Down Expand Up @@ -117,16 +117,15 @@ function do_run(array $command, array $ports = []): Process
$arguments = [
'docker', 'run', '--rm', '--init',
'--user', "{$userId}:{$groupId}",
// The image installs MkDocs system-wide, but the social plugin wants a
// writable home for its font cache.
// The social plugin wants a writable home for its font cache.
'--env', 'HOME=/tmp',
'--volume', \sprintf('%s:/mkdocs:cached', __DIR__),
'--volume', \sprintf('%s:/doc:cached', __DIR__),
// Mounted next to the docs so pages can include them, see the
// "include-markdown" directives in doc/.
'--volume', \sprintf('%s:/mkdocs/doc:cached', root() . '/doc'),
'--volume', \sprintf('%s:/mkdocs/README.md:cached', root() . '/README.md'),
'--volume', \sprintf('%s:/mkdocs/CHANGELOG.md:cached', root() . '/CHANGELOG.md'),
'--volume', \sprintf('%s:/mkdocs/example:cached', root() . '/example'),
// markdown() macros in doc/.
'--volume', \sprintf('%s:/doc/doc:cached', root() . '/doc'),
'--volume', \sprintf('%s:/doc/README.md:cached', root() . '/README.md'),
'--volume', \sprintf('%s:/doc/CHANGELOG.md:cached', root() . '/CHANGELOG.md'),
'--volume', \sprintf('%s:/doc/example:cached', root() . '/example'),
];

foreach ($ports as $port) {
Expand Down
27 changes: 27 additions & 0 deletions tools/doc/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Macros used by the documentation, see https://zensical.org/docs/compatibility/mkdocs/plugins/#macros"""

import os

ROOT = os.path.dirname(os.path.abspath(__file__))


def define_env(env):
@env.macro
def markdown(path, start=None, end=None):
"""Include a Markdown file, or only the part between the start and end markers."""
file = os.path.join(ROOT, path)
if not os.path.isfile(file):
raise FileNotFoundError(f'The file "{path}" included in "{env.page.path}" does not exist.')

with open(file) as f:
content = f.read()

for marker in (start, end):
if marker and marker not in content:
raise ValueError(f'The marker "{marker}" was not found in "{path}", included in "{env.page.path}".')
if start:
content = content.split(start, 1)[1]
if end:
content = content.split(end, 1)[0]

return content
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "base.html" %}

{% block htmltitle %}
{% if page.is_homepage %}
{% if page.meta and page.meta.title and not page.url %}
<title>{{ page.meta.title }}</title>
{% elif page.meta and page.meta.title %}
<title>{{ page.meta.title }} - Castor Docker plugin</title>
Expand Down
68 changes: 68 additions & 0 deletions tools/doc/overrides/partials/header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{# Retrieved from zensical/templates/partials/header.html to override site name #}
{% set class = "md-header" %}
{% if "navigation.tabs.sticky" in features %}
{% set class = class ~ " md-header--shadow md-header--lifted" %}
{% elif "navigation.tabs" not in features %}
{% set class = class ~ " md-header--shadow" %}
{% endif %}
<header class="{{ class }}" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="{{ lang.t('header') }}">
<a href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}" title="{{ config.site_name | e }}" class="md-header__button md-logo" aria-label="{{ config.site_name }}" data-md-component="logo">
{% include "partials/logo.html" %}
</a>
<label class="md-header__button md-icon" for="__drawer" aria-label="{{ lang.t('nav') }}">
{% set icon = config.theme.icon.menu or "material/menu" %}
{% include ".icons/" ~ icon ~ ".svg" %}
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
{# {{ config.site_name }} #}
Docker plugin
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
{% if page.meta and page.meta.title %}
{{ page.meta.title }}
{% else %}
{{ page.title }}
{% endif %}
</span>
</div>
</div>
</div>
{% if config.theme.palette %}
{% if not config.theme.palette is mapping %}
{% include "partials/palette.html" %}
{% endif %}
{% endif %}
{% if not config.theme.palette is mapping %}
{% include "partials/javascripts/palette.html" %}
{% endif %}
{% if config.extra.alternate %}
{% include "partials/alternate.html" %}
{% endif %}
{% if "search" in config.plugins %}
{% set search = config.plugins["search"] | attr("config") %}
{% if search.enabled %}
<label class="md-header__button md-icon" for="__search" aria-label="{{ lang.t('search') }}">
{% set icon = config.theme.icon.search or "material/magnify" %}
{% include ".icons/" ~ icon ~ ".svg" %}
</label>
{% include "partials/search.html" %}
{% endif %}
{% endif %}
<div class="md-header__source">
{% if config.repo_url %}
{% include "partials/source.html" %}
{% endif %}
</div>
</nav>
{% if "navigation.tabs.sticky" in features %}
{% if "navigation.tabs" in features %}
{% include "partials/tabs.html" %}
{% endif %}
{% endif %}
</header>
Loading
Loading