Skip to content

Added Markdown version of the doc available as a Composer package#3307

Open
mnocon wants to merge 21 commits into
5.0from
doc-as-composer-package
Open

Added Markdown version of the doc available as a Composer package#3307
mnocon wants to merge 21 commits into
5.0from
doc-as-composer-package

Conversation

@mnocon

@mnocon mnocon commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Target: 5.0, 6.0

This PR makes it possible to use our documentation within a DXP project, locally and offline.

The documentation is available as Markdown files in the vendor directory, making it easy for the Agents to grep for the content.

Companion PR making the skill available: ibexa/recipes-dev#252

Goal

I want people to be able to use our documentation when working on a DXP project.
There are various use cases here that we can help with (see the examples below).

My plan for this looks like this:

  • review and merge the idea
  • start tagging the documentation as a package for internal use within the Cohesivo Product Unit
  • gather feedback from all the departments (Devs, QA, Support, Design, PM - I believe all can benefit from this)
  • improve the skill/format based on that
  • make it public for the Partners and included in the DXP by default (technical note: add to require-dev in the website-skeleton)
  • write a "How to use AI with the doc" article describing this

Setup

If you want to test this locally, run:

#TMP until recipes PR is merged
composer config extra.symfony.endpoint https://api.github.com/repos/ibexa/recipes-dev/contents/index.json?ref=flex/pull-252
# TMP until package is added to Packagist
composer config repositories.documentation vcs https://github.com/mnocon/documentation-developer/
# Add the actual package
composer require --dev ibexa/documentation-developer:~5.0 --no-scripts
claude # or copilot, or other AI Agent

For now, this is using my fork for testing.

See examples below for inspiration.

Versioning

I propose the following versioning schema: DXP_MAJOR_VERSION.DXP_MINOR_VERSION.TAGGING_DATE_YYYYMMDD.

For example. for 5.0 this gives us the following versions:

  • 5.0.20260721
  • 5.0.20260725

Benefits:

  • version line matches DXP version
  • bugfix number is always increasing with time

Usage

Built-in skill

The documentation package delivers (through recipes) a skill instructing the agent how to use them.
For more info, see https://github.com/ibexa/documentation-developer/pull/3307/changes#r3623075089

Examples

You can ask any questions about Ibexa DXP. For example, ask about Admin UI configuration:

obraz

Or about the content model itself:

obraz

Or update instructions:

Screenshot 2026-07-22 at 15 32 05

Or extending the DXP:

I know that the agents are able to reverse-engineer the code better than described in the doc sometimes, but they might miss the additional steps like clearing persistence cache or adding the block to the landing page content type

Screenshot 2026-07-22 at 15 32 54 Screenshot 2026-07-22 at 15 33 03

Testing the repo itself

In case you don't have a DXP project, and just want to talk to the doc:

composer create-project --repository="{\"type\": \"vcs\", \"url\":\"https://github.com/mnocon/documentation-developer\"}" ibexa/documentation-developer:^5.0 output
cd output
claude

Note that in that case the skill will not be valid and the PHP API links to vendor/ won't resolve as well.
So maybe it's not a good idea 🤔

@github-actions

Copy link
Copy Markdown

Preview of modified files: no change to preview.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Status Count
🔍 Total 763521
🔗 Unique 15042
✅ Successful 6328
⏳ Timeouts 0
🔀 Redirected 0
👻 Excluded 757193
❓ Unknown 0
🚫 Errors 0
⛔ Unsupported 0

Full Github Actions output

Comment thread .github/workflows/release_composer_package.yaml Fixed
Comment thread .github/workflows/release_composer_package.yaml Fixed
Comment thread build_package_docs.py
use_directory_urls both sides publish as directory URLs, so the returned
dict maps 'guide/images/' -> 'content_management/images/images/'.
"""
with open(plugins_path, encoding="utf-8") as f:
Comment thread build_package_docs.py
_version_bases("https://doc.ibexa.co/projects/userguide/", version),
)
docsets = ((developer, dev_dir), (user, user_dir))
class_paths = json.loads(Path(class_map_path).read_text(encoding="utf-8"))

- name: Install dependencies
run: |
python -m pip install --upgrade pip
# the editable install from this checkout (requirements.txt: -e .) already
# provides the plugin, and pip refuses two direct references to one package.
grep -v '^ibexa-llms-txt @' user-docs/requirements.txt > user-reqs-filtered.txt
pip install -r requirements.txt -r user-reqs-filtered.txt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've discussed this with Gemini and Claude - we control ibexa/documentation-user, so it's ok.

Quoting Gemini:

Is it a real risk here?

No, if user-docs/ is entirely controlled by your team. If it’s just your own static internal repo, the risk is negligible (limited to general supply-chain risks on PyPI).

# the editable install from this checkout (requirements.txt: -e .) already
# provides the plugin, and pip refuses two direct references to one package.
grep -v '^ibexa-llms-txt @' user-docs/requirements.txt > user-reqs-filtered.txt
pip install -r requirements.txt -r user-reqs-filtered.txt
@@ -0,0 +1,57 @@
---

@mnocon mnocon Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To create the skill I've used https://github.com/agent-ecosystem/skill-validator , here's the result:

~doc-as-composer-package doc-as-composer-package *17 !1 ?1 ❯ 

skill-validator score evaluate --provider claude-cli .agents/skills/external --rescore
  scoring: ibexa-documentation/SKILL.md

Scoring skill: /Users/marek/Desktop/repos/mnocon/documentation-developer/
doc-as-composer-package/.agents/skills/external/ibexa-documentation

SKILL.md Scores
  Clarity:               5/5
  Actionability:         5/5
  Token Efficiency:      4/5
  Scope Discipline:      5/5
  Directive Precision:   4/5
  Novelty:               4/5
  ──────────────────────────────
  Overall:              4.50/5

  "A tightly scoped, highly actionable skill that 
precisely documents the local Ibexa DXP docs layout, lookup methods, 
and package update workflow with concrete commands; 
minor room to trim and a bit more explicit gating on when to fall back to web/code."
  Novel details: The novel, project-specific details a reviewer should verify are: 
the claim that `vendor/ibexa/documentation-developer/` is installed locally 
and mirrors both `doc.ibexa.co/en/latest/` (developer) 
and `doc.ibexa.co/projects/userguide/en/latest/` (user guide); 
the `developer/llms.txt`/`user/llms.txt` table-of-contents convention; 
and the package's non-standard versioning scheme 
(`MAJOR.MINOR.DATE_OF_TAGGING_YYYYMMDD`, e.g. `5.0.20260101`) 
alongwith the specific `composer outdated --direct "ibexa/documentation-*"` 
and `composer update ibexa/documentation-developer --no-scripts` commands.

I've experimented with various rewrites, but I believe the skill has reached diminishing returns already.
As the scoring is done by a LLM, the score and reasoning fluctuates a bit with every run - but it's consistently getting scored above 4.

Once we make this available internally, we'll be able to get feedback from people using it.

mnocon and others added 18 commits July 22, 2026 14:00
Trims released archives to just the generated clean Markdown (via
.gitattributes export-ignore) and adds a workflow that builds the docs,
syncs the llms.txt-generated Markdown into a tracked markdown/ directory,
and tags a release when the content changes. The require section is now
empty since the shipped payload is Markdown only, not PHP code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ting tag

Drops the push trigger and the master/main fallback for tagging, and
switches the release workflow to append today's date to whatever
patch version was last tagged for the branch, instead of hardcoding it.
Also updates .gitattributes to match the docs/ sync target.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Versions must line up 1:1 with the ibexa/* product packages (5.0.9, not
5.0.1203), so the release is now a manual workflow_dispatch that takes the
target DXP version directly (mirroring api_refs.yaml's version input),
derives the branch to build from it, and tags exactly that version.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reads extra.latest_tag_X_Y from each branch's own mkdocs.yml as the DXP
version to mirror, so doc tags stay aligned with the actual product
version (5.0.9, not an arbitrary date-only scheme). Retags when either
the generated Markdown changed or the DXP version moved since the last
tag. Scheduled runs fan out via a branch matrix with explicit ref
checkouts, since GitHub only fires `schedule` on the default branch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mnocon
mnocon force-pushed the doc-as-composer-package branch from ec3e496 to 4cc2538 Compare July 22, 2026 12:09
Comment thread composer.json
{
"name": "ibexa/documentation-developer",
"description": "This repository is the source for the developer documentation for eZ Platform, an open source CMS based on the Symfony Full Stack Framework in PHP.",
"description": "Ibexa DXP developer documentation as Markdown files, for offline reading and AI coding assistants working inside your project.",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this package contains only Markdown files and I want people to install it locally, we need to make sure it's installable and does not block any projects.

I've kept the php requirement, but we can consider moving it to require-dev as well - I don't think it matters, as anyone using composer locally will have PHP installed as well.

Alternative: add ibexa/core:~5.0 requirement so that 5.0 doc can only be installed with 5.0 DXP, but I don't think we need that

Comment thread composer.json
"ibexa/connector-actito": "~5.0.x-dev",
"ibexa/fastly": "~5.0.x-dev"
"ibexa/fastly": "~5.0.x-dev",
"ibexa/connect": "~5.0.x-dev",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added missing packages so that resolving links to vendor (from PHP API Reference) works

on:
schedule:
# Daily at 03:17 UTC. Fans out to every maintained version branch (see determine-branches).
- cron: "17 3 * * *"

@mnocon mnocon Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to run this workflow every day, and create a new tag if there's new content in the documentation.

So it's not tied to the release cycle of the DXP, it's tagged when there's something new in the doc to make sure it's up to date with what's available online.

- name: Install dependencies
run: |
python -m pip install --upgrade pip
# user-docs pins ibexa-llms-txt from the upstream git repo; drop that line —

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a clash in dependencies - PIP doesn't understand that these:

https://github.com/ibexa/documentation-user/blob/5.0/requirements.txt#L11
https://github.com/ibexa/documentation-developer/blob/5.0/requirements.txt#L11

refer to the same dependency. Hence the grep filtering to make the dependencies resolve

Comment thread .gitattributes
@@ -0,0 +1,7 @@
/* export-ignore

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file controls what is included in the released package - you can explore the tag content downloaded by Composer to see that the Markdown source files, the HTML PHP API ref etc. are not included.

The result are pure Markdown files, skill file, llms.txt files and composer.json

* Dump a map of PHP API classes referenced by the generated Markdown docs to
* their vendor-relative source paths.
*
* Usage: php tools/llm_package/dump_class_paths.php [<site_dir>...] [<output_json>]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output file looks like this:

~/De/r/m/documentation-developer/doc-as-composer-package doc-as-composer-package *17 +2 ❯ php tools/llm_package/dump_class_paths.php site output.json
Resolved 808/808 API-referenced classes into output.json
{
    "Ibexa\\Contracts\\ActivityLog\\ActivityLogServiceInterface": "ibexa/activity-log/src/contracts/ActivityLogServiceInterface.php",
    "Ibexa\\Contracts\\AdminUi\\ContentType\\ContentTypeFieldsByExpressionServiceInterface": "ibexa/admin-ui/src/contracts/ContentType/ContentTypeFieldsByExpressionServiceInterface.php",
    "Ibexa\\Contracts\\AdminUi\\Event\\ResolveVersionPreviewUrlEvent": "ibexa/admin-ui/src/contracts/Event/ResolveVersionPreviewUrlEvent.php",
    "Ibexa\\Contracts\\AdminUi\\Exception\\UnresolvedPreviewUrlException": "ibexa/admin-ui/src/contracts/Exception/UnresolvedPreviewUrlException.php",
    "Ibexa\\Contracts\\AdminUi\\Menu\\AbstractActionBuilder": "ibexa/admin-ui/src/contracts/Menu/AbstractActionBuilder.php",

required: true
default: "5.0"
type: string
devdoc_branch:

@mnocon mnocon Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added devdoc_branch and userdoc_branch so that we don't have to add any TMP commits when testing this workflow (as we currently do for the PHP API reference)

@mnocon
mnocon marked this pull request as ready for review July 22, 2026 14:01
@mnocon
mnocon requested a review from a team July 22, 2026 14:18
@ibexa-workflow-automation-1
ibexa-workflow-automation-1 Bot requested review from adriendupuis, dabrt and julitafalcondusza and removed request for a team July 22, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants