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
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
* text=auto eol=lf
/.* export-ignore
/vendor export-ignore
/node_modules export-ignore
/site export-ignore
/coverage export-ignore
/composer.lock export-ignore
/packages/*/vendor export-ignore
/packages/*/tests export-ignore
/.github export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore
Expand Down
49 changes: 48 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Release (single package)

# Packagist reads tags from this repository's root composer.json.
# This gate validates the tagged distribution; indexing is checked separately (docs/publishing.md).
# The webhook indexes the tag; publication succeeds only after a clean consumer installs it.
on:
push:
tags:
Expand Down Expand Up @@ -31,3 +31,50 @@ jobs:
- run: composer check
- run: composer mono-validate
- run: composer test:package

publish:
name: Verify Packagist and publish release
needs: package
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: write
env:
RELEASE_TAG: ${{ github.ref_name }}
RELEASE_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: none
tools: composer:v2
- run: composer install --no-interaction --prefer-dist
- name: Wait for Packagist to index this exact tag
run: |
for attempt in $(seq 1 20); do
if curl --fail --silent --show-error https://packagist.org/packages/fireflyframework/larafly.json -o "$RUNNER_TEMP/larafly.json" &&
php -r '$p = json_decode(file_get_contents($argv[1]), true); exit(($p["package"]["versions"][getenv("RELEASE_TAG")]["source"]["reference"] ?? null) === getenv("RELEASE_SHA") ? 0 : 1);' "$RUNNER_TEMP/larafly.json"; then
exit 0
fi
sleep 15
done
echo 'Packagist has not indexed the tagged commit. Check the repository webhook and rerun this job.' >&2
exit 1
- name: Install the public release and exercise its installer
run: php scripts/check-package-install.php --published
- name: Publish the verified release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 - <<'PY'
import os, pathlib, re
version = os.environ['RELEASE_TAG'].removeprefix('v')
changelog = pathlib.Path('CHANGELOG.md').read_text()
notes = re.search(r'^## \[' + re.escape(version) + r'\].*?\n(.*?)(?=^## \[|\Z)', changelog, re.M | re.S)
if notes is None:
raise SystemExit('The tag has no changelog entry')
pathlib.Path(os.environ['RUNNER_TEMP'], 'release-notes.md').write_text(notes[1].strip() + '\n')
PY
gh release view "$RELEASE_TAG" >/dev/null 2>&1 ||
gh release create "$RELEASE_TAG" --verify-tag --title "LaraFly ${RELEASE_TAG#v}" --notes-file "$RUNNER_TEMP/release-notes.md"
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ All notable changes to LaraFly are documented here. This project uses CalVer (`Y

## [Unreleased]

## [26.09.9] - 2026-09-27

### Changed

- Publish the repository root as the `firefly/firefly` library, replacing component names at the same
- Publish the repository root as the `fireflyframework/larafly` library, replacing component names at the same
version. Runtime dependencies, autoloading and Laravel discovery now belong to that package; no split
mirrors or cross-repository release credential are needed.
mirrors or cross-repository release credential are needed. The public package uses the
`fireflyframework` namespace because Packagist reserves `firefly` for another publisher.
- Gate GitHub releases on PHP 8.3–8.5 validation and a clean installation of the exact tagged commit
from Packagist, including the bundled application installer.
- Exclude local development dependencies from both release archives and copied path installations.
- Keep Lumen and component test support in development autoloading, and validate exported and copied
consumer installations in CI. The installer uses the bundled skeleton and adds Testbench explicitly
when the testing capability is requested. PostgreSQL outbox migrations are registered only for that
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<a href="docs/installation.md#requirements"><img src="https://img.shields.io/badge/php-8.3%2B-blue?logo=php&logoColor=white" alt="PHP 8.3+"></a>
<a href="docs/laravel-comparison.md"><img src="https://img.shields.io/badge/Laravel-13-FF2D20?logo=laravel&logoColor=white" alt="Laravel 13"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green" alt="License: Apache 2.0"></a>
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-26.09.8-brightgreen" alt="Version: 26.09.5"></a>
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-26.09.9-brightgreen" alt="Version: 26.09.9"></a>
<a href="docs/contributing.md#conventions"><img src="https://img.shields.io/badge/PHPStan-max-8A2BE2" alt="PHPStan: max"></a>
<a href="pint.json"><img src="https://img.shields.io/badge/code%20style-Pint-F55247" alt="Code Style: Pint"></a>
</p>
Expand Down Expand Up @@ -202,7 +202,7 @@ will have — that they are worth naming outright:

```bash
# 1 · Install the global installer once, then scaffold a new app
composer global require firefly/firefly
composer global require fireflyframework/larafly
firefly new my-app
cd my-app

Expand Down Expand Up @@ -986,22 +986,22 @@ LaraFly layers onto Laravel, it is not a standalone runtime. Full details in
**New project — the global installer:**

```bash
composer global require firefly/firefly
composer global require fireflyframework/larafly
firefly new my-app
```

**New project — bundled installer:**

```bash
composer global require firefly/firefly
composer global require fireflyframework/larafly
firefly new my-app
```

**Adding LaraFly to an existing Laravel app** — `firefly/firefly` is the complete framework library,
**Adding LaraFly to an existing Laravel app** — `fireflyframework/larafly` is the complete framework library,
developer console included:

```bash
composer require firefly/firefly
composer require fireflyframework/larafly
```

The browser dashboard (`firefly/admin`) and the API-documentation package (`firefly/openapi`) come with it. The
Expand Down Expand Up @@ -1056,7 +1056,7 @@ Full flag reference and generated-file contents: [CLI](docs/cli.md).

## Modules

One published library, `firefly/firefly`, contains the components under `packages/*` and the bundled
One published library, `fireflyframework/larafly`, contains the components under `packages/*` and the bundled
application skeleton. Its `replace` entries satisfy component requirements at the framework's version;
component names remain useful module boundaries, with their own test suites. The 32
[module guides](docs/modules/) below group them by concern:
Expand Down
13 changes: 7 additions & 6 deletions book/src-es/00-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ composer --version
La forma más rápida de iniciar una nueva aplicación LaraFly es `composer create-project`, apuntando a la plantilla `firefly/skeleton`:

```bash
composer create-project firefly/skeleton my-app
composer global require fireflyframework/larafly
firefly new my-app
cd my-app
```

Expand All @@ -50,7 +51,7 @@ cd my-app
Para cuando ese comando termina, `.env` ya existe, se ha creado el archivo de base de datos SQLite, `APP_KEY` está configurada y — el paso que más importa para este libro — **`firefly:cache` ya ha compilado los manifiestos de tu aplicación**. Todavía no has escrito una sola línea de PHP, y la ruta de arranque sin reflexión sobre la que se construye todo este framework ya está en su sitio.

!!! tip "Un instalador global, si lo prefieres"
`composer global require firefly/installer` te da un comando `firefly` en tu `PATH`. `firefly new my-app` envuelve la misma llamada a `composer create-project firefly/skeleton`, y luego ejecuta `git init` y un commit inicial por ti — el equivalente en LaraFly de `laravel new`.
`composer global require fireflyframework/larafly` te da un comando `firefly` en tu `PATH`. `firefly new my-app` entrega a Composer la plantilla incluida en la biblioteca, y luego ejecuta `git init` y un commit inicial por ti — el equivalente en LaraFly de `laravel new`.

### Qué acabas de instalar

Expand All @@ -60,15 +61,15 @@ El `composer.json` del andamiaje requiere solo dos paquetes de Firefly directame
"require": {
"php": "^8.3",
"firefly/cli": "*@dev",
"firefly/firefly": "*@dev",
"fireflyframework/larafly": "*@dev",
"laravel/framework": "^13.0"
}
```

`firefly/cli` te da los comandos `artisan firefly:*` que usarás a lo largo de este libro. `firefly/firefly` es el **metapaquete de tiempo de ejecución** — el análogo en Composer de una lista de materiales (BOM) de Maven — que arrastra toda la familia Firefly (contenedor, contexto, configuración, web, datos, cqrs, eda, seguridad, validación, resiliencia, programación, observabilidad, actuator y más) en una sola línea `require`, de modo que tu propio `composer.json` nunca tiene que enumerarlos uno a uno.
`firefly/cli` te da los comandos `artisan firefly:*` que usarás a lo largo de este libro. `fireflyframework/larafly` es el **biblioteca completa del framework**, que contiene toda la familia Firefly (contenedor, contexto, configuración, web, datos, cqrs, eda, seguridad, validación, resiliencia, programación, observabilidad, actuator y más) en una sola línea `require`, de modo que tu propio `composer.json` nunca tiene que enumerarlos uno a uno.

!!! laravel "Paridad con Laravel"
`composer create-project firefly/skeleton` es el equivalente en LaraFly de `laravel new` — y `firefly/firefly` es el equivalente de instalar el propio `laravel/framework`: una línea de dependencia que trae una pila completa y coherente en lugar de una colección de piezas versionadas de forma independiente.
`firefly new` es el equivalente en LaraFly de `laravel new` — y `fireflyframework/larafly` es el equivalente de instalar el propio `laravel/framework`: una línea de dependencia que trae una pila completa y coherente en lugar de una colección de piezas versionadas de forma independiente.

---

Expand All @@ -87,7 +88,7 @@ declare(strict_types=1);
return [];
```

No hay ningún proveedor de servicios que registrar a mano. Los propios proveedores de `firefly/cli` y `firefly/firefly` se descubren automáticamente mediante el descubrimiento de paquetes de Composer/Laravel — nunca añades una línea aquí por un paquete de Firefly.
No hay ningún proveedor de servicios que registrar a mano. Los propios proveedores de `firefly/cli` y `fireflyframework/larafly` se descubren automáticamente mediante el descubrimiento de paquetes de Composer/Laravel — nunca añades una línea aquí por un paquete de Firefly.

Segundo, `routes/web.php` también está casi vacío:

Expand Down
13 changes: 7 additions & 6 deletions book/src/00-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ composer --version
The fastest way to start a new LaraFly application is `composer create-project`, pointed at the `firefly/skeleton` template:

```bash
composer create-project firefly/skeleton my-app
composer global require fireflyframework/larafly
firefly new my-app
cd my-app
```

Expand All @@ -50,7 +51,7 @@ cd my-app
By the time that command returns, `.env` exists, a SQLite database file has been touched, `APP_KEY` is set, and — the step that matters most for this book — **`firefly:cache` has already compiled your application's manifests**. You have not written a single line of PHP yet, and the zero-reflection boot path this whole framework is built around is already in place.

!!! tip "A global installer, if you prefer it"
`composer global require firefly/installer` gives you a `firefly` command on your `PATH`. `firefly new my-app` wraps the same `composer create-project firefly/skeleton` call, then runs `git init` and an initial commit for you — the LaraFly equivalent of `laravel new`.
`composer global require fireflyframework/larafly` gives you a `firefly` command on your `PATH`. `firefly new my-app` supplies the bundled skeleton to Composer, then runs `git init` and an initial commit for you — the LaraFly equivalent of `laravel new`.

### What you just installed

Expand All @@ -60,15 +61,15 @@ The skeleton's `composer.json` requires only two Firefly packages directly:
"require": {
"php": "^8.3",
"firefly/cli": "*@dev",
"firefly/firefly": "*@dev",
"fireflyframework/larafly": "*@dev",
"laravel/framework": "^13.0"
}
```

`firefly/cli` gives you the `artisan firefly:*` commands you will use throughout this book. `firefly/firefly` is the **runtime metapackage** — the Composer analogue of a Maven BOM — that pulls in the whole Firefly family (container, context, config, web, data, cqrs, eda, security, validation, resilience, scheduling, observability, actuator, and more) in a single `require` line, so your own `composer.json` never has to enumerate them one at a time.
`firefly/cli` gives you the `artisan firefly:*` commands you will use throughout this book. `fireflyframework/larafly` is the **complete framework library**, which contains the whole Firefly family (container, context, config, web, data, cqrs, eda, security, validation, resilience, scheduling, observability, actuator, and more) in a single `require` line, so your own `composer.json` never has to enumerate them one at a time.

!!! laravel "Laravel parity"
`composer create-project firefly/skeleton` is LaraFly's counterpart to `laravel new` — and `firefly/firefly` is the counterpart of installing `laravel/framework` itself: one dependency line that brings in an entire, coherent stack rather than a collection of independently-versioned pieces.
`firefly new` is LaraFly's counterpart to `laravel new` — and `fireflyframework/larafly` is the counterpart of installing `laravel/framework` itself: one dependency line that brings in an entire, coherent stack rather than a collection of independently-versioned pieces.

---

Expand All @@ -87,7 +88,7 @@ declare(strict_types=1);
return [];
```

There is no service provider to register by hand. `firefly/cli` and `firefly/firefly`'s own providers are discovered automatically by Composer/Laravel package discovery — you never add a line here for a Firefly package.
There is no service provider to register by hand. `firefly/cli` and `fireflyframework/larafly`'s own providers are discovered automatically by Composer/Laravel package discovery — you never add a line here for a Firefly package.

Second, `routes/web.php` is almost empty too:

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "firefly/firefly",
"name": "fireflyframework/larafly",
"description": "LaraFly — the Firefly Framework for PHP.",
"type": "library",
"license": "Apache-2.0",
Expand Down Expand Up @@ -130,6 +130,7 @@
"firefly/eda-kafka": "self.version",
"firefly/eda-postgres": "self.version",
"firefly/eda-rabbitmq": "self.version",
"firefly/firefly": "self.version",
"firefly/installer": "self.version",
"firefly/kernel": "self.version",
"firefly/messaging": "self.version",
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Monorepo layout

`fireflyframework-php` publishes the root `firefly/firefly` library. All component code stays under
`fireflyframework-php` publishes the root `fireflyframework/larafly` library. All component code stays under
`packages/*`; their manifests document module requirements and namespaces and are validated together.
They are not published or installed separately. `skeleton/` is the bundled application template used by
`firefly new`. `samples/lumen` consumes the root through a copied path repository.
Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ application pre-wired with the Firefly family, a `#[Controller]` welcome page, a
`#[RestController]`/`#[Service]` pair, and `firefly:cache` already wired into `post-create-project-cmd`:

```bash
composer global require firefly/firefly
composer global require fireflyframework/larafly
firefly new my-app
cd my-app
php artisan firefly:cache
Expand All @@ -29,7 +29,7 @@ installed) — see [CLI](cli.md) for the full command reference.
Install the complete framework library, including the CLI, dashboard and API documentation:

```bash
composer require firefly/firefly
composer require fireflyframework/larafly
```

All component code is included. Optional adapters are activated by configuration and may require a PHP
Expand All @@ -55,26 +55,26 @@ php artisan firefly:cache
php artisan firefly:serve
```

## The two packages the skeleton requires
## The library and component requirement

`firefly/skeleton` is itself a `type: project` create-project template rather than something you require, and
its `composer.json` asks for exactly two Firefly packages beside `php: ^8.3` and `laravel/framework: ^13.0`:
its `composer.json` asks for the library and a CLI component requirement beside `php: ^8.3` and `laravel/framework: ^13.0`:

<!-- source: skeleton/composer.json -->

```json
"require": {
"php": "^8.3",
"firefly/cli": "*@dev",
"firefly/firefly": "*@dev",
"fireflyframework/larafly": "*@dev",
"laravel/framework": "^13.0"
},
```

- **`firefly/cli`** — the developer-experience console: `firefly:cache`/`:clear`, actuator-over-CLI
`firefly:about`/`:routes`/`:health`/`:metrics`, `firefly:oauth2:keys`, the `make:firefly-*` generator
family, and thin `firefly:serve`/`:schedule`/`:db` passthroughs. See [CLI](cli.md).
- **`firefly/firefly`** — the complete `type: library` distribution. It supplies `firefly/cli` through
- **`fireflyframework/larafly`** — the complete `type: library` distribution. It supplies `firefly/cli` through
`replace`, so both requirements resolve to the same installation. The template's CLI requirement
explicitly records its use of `firefly:cache`.

Expand Down
8 changes: 4 additions & 4 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
The bundled `firefly new` installer supplies the application template to Composer and prepares the app:

```bash
composer global require firefly/firefly
composer global require fireflyframework/larafly
firefly new my-app
cd my-app
php artisan firefly:serve
Expand All @@ -29,7 +29,7 @@ off `NewCommand::configure()`:
| `-f`, `--force` | **Empties the target directory first**, then scaffolds into it. |
| `--git` / `--no-git` | Whether to `git init` and make an initial commit. On by default. |

Every component's code is included in `firefly/firefly`. `--with` records an explicit component
Every component's code is included in `fireflyframework/larafly`. `--with` records an explicit component
requirement in the generated manifest; it does not fetch a separate framework package. Configuration
selects the active transport. `eda-postgres` needs `ext-pdo_pgsql`, `eda-kafka` needs `ext-rdkafka`,
`eda-rabbitmq` uses the included AMQP client, and `scheduling-postgres` needs a PostgreSQL connection.
Expand All @@ -46,7 +46,7 @@ cd my-app
php artisan firefly:serve
```

The generated application installs `firefly/firefly` from Packagist; before first publication, supply a
The generated application installs `fireflyframework/larafly` from Packagist; before first publication, supply a
root VCS or path repository as described in [Publishing](publishing.md).

`firefly/skeleton`'s `composer.json` wires `post-create-project-cmd` to run automatically, so by the time the
Expand All @@ -61,7 +61,7 @@ command above finishes you already have, in this order:

## What the template requires

`skeleton/composer.json` requires PHP, Laravel, `firefly/firefly` and `firefly/cli`. The library supplies
`skeleton/composer.json` requires PHP, Laravel, `fireflyframework/larafly` and `firefly/cli`. The library supplies
all framework code; the CLI requirement is satisfied by `replace`. Providers are discovered from the
root package's `extra.laravel.providers` metadata.

Expand Down
2 changes: 1 addition & 1 deletion docs/modules.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Modules

LaraFly publishes one `firefly/firefly` library containing the **29 component directories** under
LaraFly publishes one `fireflyframework/larafly` library containing the **29 component directories** under
`packages/*`, each with its own tests or metadata. The **32 guides** below explain their public surfaces.
Several components carry more than one guide: `firefly/data` answers for *Data & Repositories*,
*Relational Data* and *Transactions*. Laravel discovers the root library's providers, and configuration
Expand Down
Loading
Loading