Click the Castor logo or press Ctrl Alt T to change theme.
# GitHub Actions and releases Castor Docs is designed to be boring in CI. A package should build its documentation on every pull request, and publish documentation only from a trusted branch or release event. The important idea is simple: documentation is source code. Treat `.dev/docs` like any other maintained source, and treat `.dev/docs-dist` like an artifact. ## What to commit Commit the source documentation: ```text .dev/docs/ config.php index.md pages/ index.md guides/ configuration.md ``` Do not commit generated output: ```text .dev/docs-dist/ ``` The package should ignore `.dev/docs-dist` and let CI regenerate it. That keeps pull requests focused on the prose and examples that humans actually maintain. ## Pull request checks Every package should run the docs build as part of CI: ```json { "scripts": { "docs:build": "@php vendor/bin/castor-docs generate --source=.dev/docs --target=.dev/docs-dist", "docs:check": [ "@docs:build", "test -f .dev/docs-dist/index.html" ] } } ``` Then call `composer docs:check` in the regular CI workflow. This catches broken configuration, missing Composer metadata, invalid docs source paths, and rendering regressions before the package is merged. ## Publishing to GitHub Pages A good default is to publish documentation from the default branch as the live package documentation. The version badge will show `latest` for untagged `main` or `master` builds. ```yaml name: Publish Docs on: push: branches: [main] paths: - ".dev/docs/**" - "composer.json" - "composer.lock" - ".github/workflows/publish-docs.yml" workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: pages cancel-in-progress: false jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: shivammathur/setup-php@v2 with: php-version: "8.3" tools: composer:v2 - run: composer install --ansi --no-interaction --no-progress - run: composer docs:build - uses: actions/upload-pages-artifact@v4 with: path: .dev/docs-dist deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4 ``` This workflow overwrites the GitHub Pages site with the latest generated docs. It only runs when the documentation sources, Composer metadata, dependency lockfile, or the workflow itself changes on `main`; the manual trigger is there for rebuilds that do not need a commit. For most Castor packages, that is exactly what we want: one canonical documentation site that follows the current maintained branch. ## Publishing from releases If a package wants the public docs to update only when a release is published, trigger the Pages workflow from releases instead: ```yaml on: release: types: [published] workflow_dispatch: ``` When the workflow checks out the release tag, Castor Docs detects the exact Git tag and shows a minor version series like `1.4.x` in the sidebar. This is useful for packages where published documentation should represent the latest stable release rather than the default branch. ## Version badge behavior in CI The sidebar version badge is chosen in this order: 1. Use `composer.json`'s `version` field if it exists. 2. Otherwise, use the exact Git tag for `HEAD` if there is one. 3. Otherwise, show `latest` on `main` or `master`. 4. Otherwise, show `dev`. Semantic versions are shown as a series. For example, `v1.2.3` becomes `1.2.x`. The docs communicate compatibility without pretending that the page is tied to one patch release. ## Release Please and composer.json versions Composer packages usually do not need a `version` field when they are installed from VCS tags. Still, Castor Docs can use that field when it is present, and some teams prefer release pull requests to write the version explicitly. To make Release Please update `composer.json`, add an `extra-files` entry to `.github/release-please-config.json`: ```json { "release-type": "php", "packages": { ".": { "extra-files": [ { "type": "json", "path": "composer.json", "jsonpath": "$.version" } ] } } } ``` Then add the field to `composer.json` once: ```json { "name": "castor/example", "version": "0.1.0" } ``` After that, Release Please will include the version change in its release pull request. Castor Docs will read it, format semantic versions as a minor series, and display that in the sidebar. > [!NOTE] > If you do not want to keep a `version` field in `composer.json`, do nothing. Tagged release builds and default branch builds are already detected automatically.
Castor ecosystem