Skip to content

Commit

Permalink
Add command to build standalone binary
Browse files Browse the repository at this point in the history
  • Loading branch information
tigitz committed Feb 2, 2024
1 parent 5679851 commit 48a389e
Show file tree
Hide file tree
Showing 11 changed files with 400 additions and 39 deletions.
6 changes: 3 additions & 3 deletions .github/actions/phar/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ runs:
shell: bash
working-directory: tools/phar

- name: Compile phar Linux
- name: Build Castor PHAR Archive for Linux
run: bin/castor castor:phar:linux
shell: bash

- name: Compile phar Darwin
- name: Build Castor PHAR Archive for Darwin
run: bin/castor castor:phar:darwin
shell: bash

- name: Compile phar Windows
- name: Build Castor PHAR Archive for Windows
run: bin/castor castor:phar:windows
shell: bash

Expand Down
44 changes: 37 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,34 @@ jobs:
REQUIRE_DEV: true

phpunit:
name: "PHPUnit on ${{ matrix.php }} ${{ matrix.phar && '(with phar)' || '' }}"
name: "PHPUnit on ${{ matrix.php }} | Castor from ${{ matrix.castor.method }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [ "8.1", "8.2", "8.3" ]
phar: [ false ]
include:
- php: "8.1"
phar: true
castor:
path: 'bin/castor'
method: 'vendor'
- php: "8.1"
castor:
path: 'tools/phar/build/castor.linux-amd64.phar'
method: 'phar'
- php: "8.1"
castor:
path: 'compiled-castor'
method: 'binary'
build-options: '--php-extensions=mbstring,phar,posix,tokenizer,pcntl'
- php: "8.2"
castor:
path: 'bin/castor'
method: 'vendor'
- php: "8.3"
castor:
path: 'bin/castor'
method: 'vendor'

steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -62,10 +80,22 @@ jobs:
run: composer install --prefer-dist --no-progress --optimize-autoloader --classmap-authoritative
working-directory: tools/phar

- name: Compile phar Linux
- name: Build Castor PHAR Archive for Linux
run: bin/castor castor:phar:linux
shell: bash
if: matrix.phar
if: matrix.castor.method == 'phar' || matrix.castor.method == 'binary'

# - name: Cache PHP static building artifacts
# uses: actions/cache@v4
# with:
# path: |
# /tmp/castor-php-static-compiler
# key: php-static-build-cache-${{ hashFiles('src/Console/Command/CompileCommand.php', 'tests/CompileCommandTest.php') }}

- name: Compile Custom Built PHP along Castor PHAR Archive for Linux
run: bin/castor compile tools/phar/build/castor.linux-amd64.phar ${{ matrix.castor.build-options }}
shell: bash
if: matrix.castor.method == 'binary'

- name: Link box
run: sudo ln -s $GITHUB_WORKSPACE/tools/phar/vendor/bin/box /usr/local/bin/box
Expand All @@ -76,7 +106,7 @@ jobs:
- name: Run tests
run: vendor/bin/simple-phpunit
env:
CASTOR_BIN: ${{ github.workspace }}/${{ matrix.phar && 'tools/phar/build/castor.linux-amd64.phar' || 'bin/castor'}}
CASTOR_BIN: ${{ github.workspace }}/${{ matrix.castor.path }}

phar:
name: Ensure PHAR is OK
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Add `wait_for_docker_container()` function to wait for a docker container to be ready
* Add `AsSymfonyTask` attribute to map Symfony Command
* Add a `debug` command
* Add a `compile` command that puts together a customizable PHP binary with a repacked castor app into one executable file
* Add `Context->name` property (automatically set by the application)
* Edited the duration of update check from `60 days` to `24 hours`
* Revise the usage of the terms `command` and `task` for consistency through code and docs.
Expand Down
51 changes: 51 additions & 0 deletions doc/going-further/compile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Compiling your application into a standalone binary

[Putting your Castor application into a PHAR archive](repack.md) can be a good way to easily share and use it in various environments.

However, you need to ensure that PHP is installed and configured correctly in all the environments where you want to use your Castor app.
This can be a hassle, especially if you don't have control over the environments.

To make things simpler, Castor's `compile` command can help by creating a customizable PHP binary with a PHAR archive, making one executable file that can be used in any setting.

Just pass your repacked Castor app PHAR as an argument of this command.

## Pre-requisites

Follow the [`repack` documentation](repack.md) to output a PHAR archive of your Castor app.

## Running the Compile Command

To compile your Castor application, navigate to your project directory and run:

```bash
vendor/bin/castor compile my-custom-castor-app.phar
```

> [!WARNING]
> Compiling is not supported yet on Windows.
### Options

Make sure to take a look at the command description to see all the available options:
```bash
vendor/bin/castor compile -h
``````
### Behavior

The `compile` command performs several steps:

1. Downloads or uses an existing Static PHP CLI tool to compile PHP and the PHAR archive into a binary.
2. If required, it automatically installs dependencies and compiles PHP with the specified extensions.
3. Combines the compiled PHP and your PHAR file into a single executable.

## Post-Compilation

Once the compilation is finished, your Castor application is transformed into a standalone binary named `compiled-castor` by default (you can use the `--output=` option to change it).

This binary is now ready to be distributed and run in environments that do not have PHP installed.

You can simply run it like any other executable:

```bash
./compiled-castor
```
1 change: 1 addition & 0 deletions doc/going-further/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

* [Listening to events](events.md)
* [Repacking your application in a new phar](repack.md)
* [Compiling your application in a standalone binary](compile.md)

## Examples

Expand Down
10 changes: 10 additions & 0 deletions doc/going-further/repack.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
You have created a Castor application, with many tasks, and you want to
distribute it as a single phar file? Castor can help you with that.

## Pre-requisites

In your project, install Castor as a dependency:

```bash
Expand All @@ -18,6 +20,8 @@ configuration. See the [PHP
documentation](https://www.php.net/manual/en/phar.configuration.php#ini.phar.readonly) to disabled
`phar.readonly`.

## Running the Repack Command

Then, run the repack command to create the new phar:

```
Expand All @@ -34,3 +38,9 @@ vendor/bin/castor repack --help
> Castor will automatically import all files in the current directly.
> So ensure to have the less files possible in the directory where you run the
> repack task to avoid including useless files in the phar.
## Going further

Packaging your Castor app as a PHAR archive simplifies distribution but requires PHP setup on target systems.

[Castor's `compile` command](compile.md) streamlines this by embedding the PHAR in a PHP binary, creating a standalone executable for diverse environments
5 changes: 4 additions & 1 deletion src/Console/ApplicationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Castor\Console;

use Castor\Console\Command\CompileCommand;
use Castor\Console\Command\DebugCommand;
use Castor\Console\Command\RepackCommand;
use Castor\ContextRegistry;
Expand Down Expand Up @@ -45,6 +46,7 @@ public static function create(): SymfonyApplication
$cacheDir = PlatformUtil::getCacheDirectory();
$cache = new FilesystemAdapter(directory: $cacheDir);
$logger = new Logger('castor', [], [new ProcessProcessor()]);
$fs = new Filesystem();

/** @var SymfonyApplication */
// @phpstan-ignore-next-line
Expand All @@ -56,7 +58,7 @@ public static function create(): SymfonyApplication
new ExpressionLanguage($contextRegistry),
new StubsGenerator($logger),
$logger,
new Filesystem(),
$fs,
$httpClient,
$cache,
new WaitForHelper($httpClient, $logger),
Expand All @@ -67,6 +69,7 @@ public static function create(): SymfonyApplication

if (!class_exists(\RepackedApplication::class)) {
$application->add(new RepackCommand());
$application->add(new CompileCommand($httpClient, $fs));
}

return $application;
Expand Down
Loading

0 comments on commit 48a389e

Please sign in to comment.