Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command to build standalone binary #260

Merged
merged 1 commit into from
Feb 14, 2024

Conversation

tigitz
Copy link
Contributor

@tigitz tigitz commented Jan 30, 2024

Fixes #257

I've added a compile command, similar to repack. Because compiling statically also means repacking the app, I've reused the repack command options into compile and set it to automatically run at the start of the compilation process.

All the files needed to build the final binary are stored in /tmp/castor-php-static-compiler folder and cached in the CI with a cache key based on src/Console/Command/CompileCommand.php and tests/CompileCommandTest.php.

Since this process includes downloading and building PHP source, it's no surprise that the test suite runs 3 minutes slower when cache is not warm. Fortunately, it will happen only when src/Console/Command/CompileCommand.php or tests/CompileCommandTest.php is modified and thus have a very minimal impact overall.

Here's the compile -h output for reference:

Usage:
  compile [options]

Options:
      --app-name=APP-NAME              The name of the phar application [default: "my-app"]
      --app-version=APP-VERSION        The version of the phar application [default: "1.0.0"]
      --os=OS                          The targeted OS [default: "linux"]
      --arch=ARCH                      Target architecture for PHP compilation [default: "x86_64"]
      --php-version=PHP-VERSION        PHP version in major.minor format [default: "8.2"]
      --php-extensions=PHP-EXTENSIONS  PHP extensions required, in a comma-separated format. Defaults are the minimum required to run a basic "Hello World" task in Castor. [default: "mbstring,phar,posix,tokenizer"]
      --php-rebuild                    Force PHP build compilation.
  -h, --help                           Display help for the given command. When no command is given display help for the list command
  -q, --quiet                          Do not output any message
  -V, --version                        Display this application version
      --ansi|--no-ansi                 Force (or disable --no-ansi) ANSI output
  -n, --no-interaction                 Do not ask any interactive question
  -v|vv|vvv, --verbose                 Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Here's a cold php vendor/bin/castor compile run output example:


Executing the repack command to build your Castor app as a PHAR archive.
------------------------------------------------------------------------


    ____
   / __ )____  _  __
  / __  / __ \| |/_/
 / /_/ / /_/ />  <
/_____/\____/_/|_|


Box version 4.6.1@048e634 2023-12-21 12:09:11 UTC

 // Loading the configuration file ".box.json".                                 

🔨  Building the PHAR "/home/psegatori/www/castor-app-as-binary/my-app.linux.phar"

? Removing the existing PHAR "/home/psegatori/www/castor-app-as-binary/my-app.linux.phar"
? Checking Composer compatibility
    > Supported version detected
? Registering compactors
  + KevinGH\Box\Compactor\Php
? Adding main file: /home/psegatori/www/castor-app-as-binary/.main.php
? Skip requirements checker
? Adding binary files
    > 1 file(s)
? Auto-discover files? Yes
? Exclude dev files? Yes
? Adding files
    > 1409 file(s)
? Generating new stub
  - Using shebang line: #!/usr/bin/env php
  - Using banner:
    > Generated by Humbug Box 4.6.1@048e634.
    > 
    > @link https://github.com/humbug/box
? Dumping the Composer autoloader
? Removing the Composer dump artefacts
? Compressing with the algorithm "GZ"
    > Warning: the extension "zlib" will now be required to execute the PHAR
? Setting file permissions to 0755
* Done.

💡  1 recommendation found:
    - The "base-path" setting can be omitted since is set to its default value
⚠️  1 warning found:
    - The "annotations" setting has been set but is ignored since no PHP compactor has been configured

 // PHAR: 1418 files (2.66MB)                                                   
 // You can inspect the generated PHAR with the "info" command.                 

 // Memory usage: 23.62MB (peak: 29.82MB), time: <1sec                          

Compiling PHP and your Castor app PHAR archive into a standalone binary
-----------------------------------------------------------------------

 Using the static-php-cli (spc) tool from "/tmp/castor-php-static-compiler/spc"
 Running command: '/tmp/castor-php-static-compiler/spc' 'doctor' '--auto-fix'
     _        _   _                 _           
 ___| |_ __ _| |_(_) ___      _ __ | |__  _ __  
/ __| __/ _` | __| |/ __|____| '_ \| '_ \| '_ \ 
\__ \ || (_| | |_| | (_|_____| |_) | | | | |_) |
|___/\__\__,_|\__|_|\___|    | .__/|_| |_| .__/   v2.1.0-beta.1
                             |_|         |_|    
Checking if current OS are supported ... Linux x86_64 ubuntu, supported
Checking if necessary tools are installed ... ok
Checking if musl-wrapper is installed ... ok
Checking if musl-cross-make is installed ... ok
Checking if necessary linux headers are installed ... ok
Doctor check complete !
 Running command: '/tmp/castor-php-static-compiler/spc' 'download' '--for-extensions=mbstring,phar,posix,tokenizer' '--with-php=8.2'
     _        _   _                 _           
 ___| |_ __ _| |_(_) ___      _ __ | |__  _ __  
/ __| __/ _` | __| |/ __|____| '_ \| '_ \| '_ \ 
\__ \ || (_| | |_| | (_|_____| |_) | | | | |_) |
|___/\__\__,_|\__|_|\___|    | .__/|_| |_| .__/   v2.1.0-beta.1
                             |_|         |_|    
[11:07:48] [INFO] Fetching source php-src [1/4]
[11:07:48] [NOTI] source [php-src] already downloaded: php-8.2.15.tar.gz
[11:07:48] [INFO] Fetching source micro [2/4]
[11:07:48] [NOTI] source [micro] already downloaded: micro
[11:07:48] [INFO] Fetching source pkg-config [3/4]
[11:07:48] [NOTI] source [pkg-config] already downloaded: pkg-config-0.29.2.tar.gz
[11:07:48] [INFO] Fetching source zlib [4/4]
[11:07:48] [NOTI] source [zlib] already downloaded: zlib-1.3.1.tar.gz
[11:07:48] [INFO] Download complete, used 0.013 s !
 Running command: '/tmp/castor-php-static-compiler/spc' 'build' 'mbstring,phar,posix,tokenizer' '--build-micro' '--arch=x86_64' '-r'
     _        _   _                 _           
 ___| |_ __ _| |_(_) ___      _ __ | |__  _ __  
/ __| __/ _` | __| |/ __|____| '_ \| '_ \| '_ \ 
\__ \ || (_| | |_| | (_|_____| |_) | | | | |_) |
|___/\__\__,_|\__|_|\___|    | .__/|_| |_| .__/   v2.1.0-beta.1
                             |_|         |_|    
[11:07:48] [INFO] [EXEC] echo | x86_64-linux-musl-gcc -E -x c - -march=corei7 2>/dev/null
[11:07:48] [INFO] [EXEC] echo | x86_64-linux-musl-gcc -E -x c - -mtune=core-avx2 2>/dev/null
[11:07:48] [INFO] Build OS:       Linux (x86_64)
[11:07:48] [INFO] Build SAPI:     micro
[11:07:48] [INFO] Extensions (5): mbstring, zlib, phar, posix, tokenizer
[11:07:48] [INFO] Libraries (1):  zlib
[11:07:48] [INFO] Strip Binaries: yes
[11:07:48] [INFO] Enable ZTS:     no
[11:07:48] [WARN] Some extensions will be enabled due to dependencies: zlib
[11:07:48] [INFO] Build will start after 2s ...
[11:07:50] [INFO] Building required library [pkg-config]
[11:07:50] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/pkg-config
[11:07:50] [INFO] [EXEC] LDFLAGS=--static ./configure --disable-shared --enable-static --with-internal-glib --prefix=/tmp/castor-php-static-compiler/buildroot --without-sysroot --without-system-include-path --without-system-library-path --without-pc-path
[11:08:05] [INFO] [EXEC] make clean
[11:08:05] [INFO] [EXEC] make -j20
[11:08:09] [INFO] [EXEC] make install
[11:08:09] [INFO] lib [pkg-config] build success
[11:08:09] [INFO] Building required library [zlib]
[11:08:09] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/zlib
[11:08:09] [INFO] [EXEC] ./configure --static --prefix=
[11:08:09] [INFO] [EXEC] make clean
[11:08:09] [INFO] [EXEC] make -j20
[11:08:10] [INFO] [EXEC] make install DESTDIR=/tmp/castor-php-static-compiler/buildroot
[11:08:10] [INFO] Patching library [zlib] pkgconfig
[11:08:10] [INFO] lib [zlib] build success
[11:08:10] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/php-src
[11:08:10] [INFO] [EXEC] ./buildconf --force
[11:08:12] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/php-src
[11:08:12] [INFO] mbstring is using --enable-mbstring --disable-mbregex
[11:08:12] [INFO] zlib is using --with-zlib --with-zlib-dir="/tmp/castor-php-static-compiler/buildroot"
[11:08:12] [INFO] phar is using --enable-phar 
[11:08:12] [INFO] posix is using --enable-posix 
[11:08:12] [INFO] tokenizer is using --enable-tokenizer 
[11:08:12] [INFO] [EXEC] LD_LIBRARY_PATH=/usr/local/musl/x86_64-linux-musl/lib ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg --disable-cli --disable-fpm --disable-embed --enable-micro=all-static --enable-mbstring --disable-mbregex --with-zlib --with-zlib-dir="/tmp/castor-php-static-compiler/buildroot" --enable-phar --enable-posix --enable-tokenizer CFLAGS='' CPPFLAGS='-I/tmp/castor-php-static-compiler/buildroot/include' LDFLAGS='-L/tmp/castor-php-static-compiler/buildroot/lib' LIBS='-ldl -lpthread' 
[11:08:25] [INFO] cleaning up
[11:08:25] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/php-src
[11:08:25] [INFO] [EXEC] make clean
[11:08:25] [INFO] building micro
patching file ext/phar/phar.c
[11:08:25] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/php-src
[11:08:25] [INFO] [EXEC] sed -i "s|//lib|/lib|g" Makefile
[11:08:25] [INFO] [EXEC] make -j20 EXTRA_CFLAGS='-g0 -Os -fno-ident -fPIE -Xcompiler -march=corei7 -Xcompiler -mtune=core-avx2' EXTRA_LIBS='/tmp/castor-php-static-compiler/buildroot/lib/libz.a  ' EXTRA_LDFLAGS_PROGRAM=' -all-static' micro
[11:09:00] [INFO] Entering dir: /tmp/castor-php-static-compiler/source/php-src/sapi/micro
[11:09:00] [INFO] [EXEC] strip --strip-all micro.sfx
[11:09:00] [INFO] Deploying micro file
[11:09:00] [INFO] [EXEC] cp '/tmp/castor-php-static-compiler/source/php-src/sapi/micro/micro.sfx' '/tmp/castor-php-static-compiler/buildroot/bin/'
patching file ext/phar/phar.c
[11:09:00] [INFO] [EXEC] /tmp/castor-php-static-compiler/source/hello.exe
[11:09:00] [INFO] Build complete, used 71.625 s !
[11:09:00] [INFO] phpmicro binary path: /tmp/castor-php-static-compiler/buildroot/bin/micro.sfx
[11:09:00] [INFO] License path: /tmp/castor-php-static-compiler/buildroot/license/
 Running command: '/tmp/castor-php-static-compiler/spc' 'micro:combine' '/home/psegatori/www/castor-app-as-binary/my-app.linux.phar' '--output=/home/psegatori/www/castor-app-as-binary/my-app'
     _        _   _                 _           
 ___| |_ __ _| |_(_) ___      _ __ | |__  _ __  
/ __| __/ _` | __| |/ __|____| '_ \| '_ \| '_ \ 
\__ \ || (_| | |_| | (_|_____| |_) | | | | |_) |
|___/\__\__,_|\__|_|\___|    | .__/|_| |_| .__/   v2.1.0-beta.1
                             |_|         |_|    
Combine success! Binary file: /home/psegatori/www/castor-app-as-binary/my-app

TODO:

  • Add tests for macos ?
  • Add docs

@tigitz tigitz force-pushed the add-compile-command branch 5 times, most recently from 6907e99 to 34ab073 Compare January 31, 2024 11:13
@tigitz
Copy link
Contributor Author

tigitz commented Jan 31, 2024

@lyrixx @pyrech, PR ready for initial review. Will proceed with remaining tasks post-feedback 👍

Copy link
Member

@lyrixx lyrixx left a comment

Choose a reason for hiding this comment

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

Love it 👍🏼 ❤️

I'll need to try this locally, but this is a very good start!

src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
timeout: 5 * 60
);
$io->text('Running command: ' . $installSPCDepsProcess->getCommandLine());
$installSPCDepsProcess->mustRun(fn ($type, $buffer) => print ($buffer));
Copy link
Member

Choose a reason for hiding this comment

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

tty must be enabled, to interact with the process?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, no need to interact with the sub processes. This line is just copied from the https://github.com/jolicode/castor/blob/main/src/Console/Command/RepackCommand.php#L109 to output the subprocess output. Is there a more appropriate way to do this?

Copy link
Member

Choose a reason for hiding this comment

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

The last time I run the doctor cmd, it asked me few things. IIRC, "do you want to install XXX", and then type my password

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is intriguing, it's passing the CI test with no issues. I'll delete the build tools on my computer and then attempt to run compile to see what needs to be fixed.

src/Console/Command/CompileCommand.php Show resolved Hide resolved
@lyrixx
Copy link
Member

lyrixx commented Jan 31, 2024

You'll also need to

  • Add some documentation
  • Add a note in the changelog

@tigitz tigitz force-pushed the add-compile-command branch 2 times, most recently from b48fdc1 to d8b7ee4 Compare January 31, 2024 16:12
@tigitz
Copy link
Contributor Author

tigitz commented Jan 31, 2024

@lyrixx I have implemented your feedbacks and pushed a single commit to ease the review.

I'll squash and rebase before merge.

Copy link
Member

@lyrixx lyrixx left a comment

Choose a reason for hiding this comment

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

Yeah! Except two little nitpick, it's okay for me!

I'll need to test it locally before the merge. I'll try this ASAP.

src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/RepackCommand.php Outdated Show resolved Hide resolved
@tigitz tigitz force-pushed the add-compile-command branch 4 times, most recently from ae3e176 to 387b186 Compare January 31, 2024 18:58
@lyrixx
Copy link
Member

lyrixx commented Feb 1, 2024

I realized something, since you "pack" the application before compiling it, it's not possible to edit the PHP code anymore, right? Could it be a drawback? For example, we (as castor team) could not distribute castor as a static binary?

If I'm right, is it possible to make the packing opt-in?

@tigitz
Copy link
Contributor Author

tigitz commented Feb 1, 2024

You're right, I'll explore ways to elegantly handle both cases in a single command.

Since one requires to run from vendor/bin and the other from the phar archive.

Also that would make all the repacking options superfluous for this case.

Since both behaviors end up merging a custom built php and a phar archive, I'm wondering if the compile command responsibility could be just that. Just passing php build options and the phar path, whether it's a repacked castor app or the castor tool itself.

But I liked the simplicity of having both the repack and compile in a single command. Not sure I would want to lose that and force users to run both commands separately.

@lyrixx
Copy link
Member

lyrixx commented Feb 1, 2024

I let you explore 💛

@lyrixx
Copy link
Member

lyrixx commented Feb 1, 2024

I merged #265 ; Now we test all examples (all tests actually) with a specific binary

  • bin/castor
  • tools/phar/build/castor.linux-amd64.phar (a phar)

So you can add your compile binary to the list :)

@tigitz tigitz force-pushed the add-compile-command branch 4 times, most recently from 2287288 to 971bc6b Compare February 2, 2024 12:51
@tigitz
Copy link
Contributor Author

tigitz commented Feb 2, 2024

Some updates:

I've decided to simplify the compile command to handle "Phar + Custom PHP build compilation."

This means it will now be able to support compiling the castor phar tool or a repacked phar castor apps.

I've thoroughly documented the process for compiling a repacked phar castor app in the docs, so for those who previously needed to do two steps instead of one, it won't be a huge obstacle.

I've also updated the CI to run the test suite with the compiled binary, and it revealed some confusing issues that I still need to understand how to fix. This seems to only happen in a phpunit environment.

When I run ./compiled-castor cd:directory, it gives this result:

/home/psegatori/www/castor
/home/psegatori/www/castor/src/Attribute
/home/psegatori/www/castor

And running: CASTOR_BIN=compiled-castor php vendor/bin/simple-phpunit --stop-on-failure | less gives:

1) Castor\Tests\Examples\CdDirectoryTest::testCdDirectory
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'...\n
-.../src/Attribute\n
-...\n
-'
+Binary String: [a long string of numbers and letters]

I'll try to investigate more deeply soon.

@tigitz tigitz force-pushed the add-compile-command branch 2 times, most recently from 1d39713 to 7718423 Compare February 12, 2024 14:08
@tigitz
Copy link
Contributor Author

tigitz commented Feb 12, 2024

My previous issue was related to tests running tasks with \PHP_BINARY $SERVER['CASTOR_BIN'] while the compiled CASTOR_BIN has the php binary included and doesnt need to be run through PHP.

I've fixed it by introducing a PHP_BIN env var that when unset or set to an empty string (like in CI), it fallback to \PHP_BINARY. When set to 'none' it's not included at all in the command line and only CASTOR_BIN is used.

The remaining issue is a mistery to me

When allowFailure is set to true for a run function that points to a non existing binary like i_do_not_exist, through castor phar or bin/castor, the process output on the standard output sh: 1: i_do_not_exist: not found while the compiled binary output it on the error output along with the exception error message.

On compiled version:

/home/psegatori/www/castor/tests/Examples/Generated/FailureFailureTest.php:16:
string(0) ""
/home/psegatori/www/castor/tests/Examples/Generated/FailureFailureTest.php:17:
string(199) "sh: 1: i_do_not_exist: not found

In failure.php line 12:
                                        
  The command "i_do_not_exist" failed.  
                                        

failure:failure

"

On PHAR and bin/castor version:

/home/psegatori/www/castor/tests/Examples/Generated/FailureFailureTest.php:16:
string(34) "sh: 1: i_do_not_exist: not found
"
/home/psegatori/www/castor/tests/Examples/Generated/FailureFailureTest.php:17:
string(166) "
In failure.php line 12:
                                        
  The command "i_do_not_exist" failed.  
                                        

failure:failure

"

Any ideas where it could come from ? If no quick solutions comes up I suggest we support both outputs in tests and ship it because I don't think it's worth blocking the feature as the whole IMO .

@lyrixx WDYT ?

Copy link
Member

@lyrixx lyrixx left a comment

Choose a reason for hiding this comment

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

I'll review the rest of the code later.

About the issue, I may have a lead. The SAPI is micro, can you try to change it to cli ? Because ATM, it breaks fews things, like call to dump() (it outputs in HTML format)

.github/actions/phar/action.yaml Outdated Show resolved Hide resolved
.github/workflows/ci.yml Outdated Show resolved Hide resolved
.github/workflows/ci.yml Outdated Show resolved Hide resolved
@lyrixx
Copy link
Member

lyrixx commented Feb 12, 2024

Any ideas where it could come from ? If no quick solutions comes up I suggest we support both outputs in tests and ship it because I don't think it's worth blocking the feature as the whole IMO .

Yes, found it.

With the static binary:

proc_open('echo 1 >/dev/null', [['pty'], ['pty'], ['pty']], $pipes)
Warning: proc_open(): PTY (pseudoterminal) not supported on this system  

IMHO, this issue should be reported upstream (I'll do 👍🏼 - see crazywhalecc/static-php-cli#335)

In the meantime, I'll perpare a PR to make the test more stable 👍🏼 (#276)

Copy link
Member

@lyrixx lyrixx left a comment

Choose a reason for hiding this comment

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

This is very good 👏🏼 👏🏼 👏🏼 👏🏼

I love it.

tests/TaskTestCase.php Outdated Show resolved Hide resolved
tools/php-cs-fixer/composer.json Outdated Show resolved Hide resolved
.github/workflows/ci.yml Outdated Show resolved Hide resolved
doc/going-further/compile.md Outdated Show resolved Hide resolved
doc/going-further/compile.md Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Outdated Show resolved Hide resolved
src/Console/Command/CompileCommand.php Show resolved Hide resolved
@tigitz tigitz force-pushed the add-compile-command branch 5 times, most recently from 1f9f557 to 28e5836 Compare February 12, 2024 23:28
@lyrixx
Copy link
Member

lyrixx commented Feb 13, 2024

Did you search for the sapi name? Do you think I should report it upstream?

@tigitz
Copy link
Contributor Author

tigitz commented Feb 13, 2024

Did you search for the sapi name? Do you think I should report it upstream?

@lyrixx This is tricky because from the project perspective I think it's reasonable to define the SAPI as micro if you want to let your users have separate logic while running on the micro version instead of native cli.

Thinking about it there's 3 ways to "solve" this:

  1. Ask SPC or phpmicro maintainers to introduce a way to build phpmicro with 'cli' as PHP_SAPI This is already available see Add command to build standalone binary #260 (comment)
  2. Ask library maintainers to support micro as \PHP_SAPI now that it becomes popular and stable
  3. Ask SPC to add support for runkit7 extension and use runkit7_constant_redefine at castor start

My guess is number 3 would be the fastest path to fix the issue.

@tigitz
Copy link
Contributor Author

tigitz commented Feb 13, 2024

@lyrixx just discovered the --with-micro-fake-cli option in spc build command. It does exactly what we need 🎊, I'll update the compile command.

@lyrixx
Copy link
Member

lyrixx commented Feb 13, 2024

Awesome 🎉 ! Did you notice the failing test?

@tigitz
Copy link
Contributor Author

tigitz commented Feb 13, 2024

Awesome 🎉 ! Did you notice the failing test?

@lyrixx yes i'm working on a better way to generate a cache key from the build options so that the build made to generate the compiled binary will not use the cache from the CompileCommandTest.php

@tigitz tigitz force-pushed the add-compile-command branch 6 times, most recently from ec3f910 to 846d265 Compare February 13, 2024 10:24
@tigitz tigitz force-pushed the add-compile-command branch 2 times, most recently from 7f03f8a to 3d45dc6 Compare February 13, 2024 11:27
@tigitz
Copy link
Contributor Author

tigitz commented Feb 13, 2024

I've introduced a method to generate a cache key based on php build options and the command file hash:

https://github.com/jolicode/castor/pull/260/files#diff-bf18146638a98fcf234bd0b8067e0910e43e91fdcb09f3ef76c0707762537b2aR205

That allows to reuse download or built artifacts when no build options change.

I've also updated the CI worfklow to cache those artifacts. It was a litlle bit tricky but hopefully comments are enough to explain.

Comment on lines +92 to +95
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
key: dynamic-key-${{ github.run_id }}
restore-keys: |
php-static-building-artifacts-cache-
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this part, It could be written:

Suggested change
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
key: dynamic-key-${{ github.run_id }}
restore-keys: |
php-static-building-artifacts-cache-
key: php-static-building-artifacts-cache

More over in the Save PHP static building artifacts cache the key could be only php-static-building-artifacts-cache`

see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key

Copy link
Contributor Author

@tigitz tigitz Feb 13, 2024

Choose a reason for hiding this comment

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

This was my initial idea, unfortunately it doesn't work as expected.

When the restore action with key: X is executed, it looks for a cache[X] and use it (hit) if it exists.
When the save action with key: X is executed, it tries to save cache[X] but if fails if it already exists, it doesn't update the cache key.

And that's not what we want because when a new arg is added to the build command, a new directory is created: /home/runner/.cache/castor/castor-php-static-compiler/{new_compile_command_build_hash}/* and we want to update the cache with this new build artifacts.

If the current config what's happening is:

Run 1

  • Restore Action:
    • Does dynamic-key-${{ github.run_id }} cache hit ? No
    • Does php-static-building-artifacts-cache-* cache hit ? No
  • PHP Build
    • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{compiler_test_command}/*
    • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{build_compiler_for_CASTOR_BIN}/*
  • Save Action:
    • Save /home/runner/.cache/castor/castor-php-static-compiler/* as key: php-static-building-artifacts-cache-XXX where XXX is hash(castor-php-static-compiler/*)

Run 2

  • Restore Action:
    • Does dynamic-key-${{ github.run_id }} cache hit ? No
    • Does php-static-building-artifacts-cache-* cache hit ? Yes it founds php-static-building-artifacts-cache-XXX
  • PHP Build
    • Use artifacts cached in /home/runner/.cache/castor/castor-php-static-compiler/**/*, no build
  • Save Action:
    • Tries to save /home/runner/.cache/castor/castor-php-static-compiler/* as key: php-static-building-artifacts-cache-XXX but fails. It's ok no new artifacts were generated anyway.

Run 3, new compilation is added or options of existing build are changed in CompileCommandTest for example:

  • Restore Action:
    • Does dynamic-key-${{ github.run_id }} cache hit ? No
    • Does php-static-building-artifacts-cache-* cache hit ? Yes, restore from Run 1
  • PHP Build
    • Build hash is different than Run 1, generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{compiler_test_command}/*
    • Build hash is same as Run 1, reuse artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{build_compiler_for_CASTOR_BIN}/*
  • Save Action:
    • Save /home/runner/.cache/castor/castor-php-static-compiler/* as key: php-static-building-artifacts-cache-YYY where YYY is a new hash of castor-php-static-compiler/* because new artifacts where generated since XXX

Copy link
Member

@lyrixx lyrixx Feb 13, 2024

Choose a reason for hiding this comment

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

There are two folders

  • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{compiler_test_command}/*
  • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{build_compiler_for_CASTOR_BIN}/*

because

  • there is one for castor itself?
  • there is another one for tests/CompileCommandTest.php

If yes, I almost got it, but not perfectly :)
If not I'm totally lost 😅

Anyway, I'll approve the PR, play a bit with it, with the cache, etc :)

Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes exactly! Both build are not using the same extensions, the one in the test has less extension, it just makes sure it compiles and can run a hello world.

The compiled castor has more extensions because it needs to rune the whole suit of examples.

Comment on lines +92 to +95
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
key: dynamic-key-${{ github.run_id }}
restore-keys: |
php-static-building-artifacts-cache-
Copy link
Member

@lyrixx lyrixx Feb 13, 2024

Choose a reason for hiding this comment

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

There are two folders

  • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{compiler_test_command}/*
  • Generate artifacts in /home/runner/.cache/castor/castor-php-static-compiler/{build_compiler_for_CASTOR_BIN}/*

because

  • there is one for castor itself?
  • there is another one for tests/CompileCommandTest.php

If yes, I almost got it, but not perfectly :)
If not I'm totally lost 😅

Anyway, I'll approve the PR, play a bit with it, with the cache, etc :)

Thanks

Copy link
Member

@pyrech pyrech left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the hard work. I probably don't understand every details, but it looks good to me in this state. Let's merge it and play with it 💛 🎉

@lyrixx
Copy link
Member

lyrixx commented Feb 14, 2024

thanks a lot for the hard work! 💛

I'm merging this PR, and I also prepare another one fix few things :)

@lyrixx lyrixx merged commit 08bb3f0 into jolicode:main Feb 14, 2024
16 checks passed
@tigitz
Copy link
Contributor Author

tigitz commented Feb 15, 2024

@lyrixx @pyrech thank you guys for being open to the idea in the first place 😊

Despite being a tricky PR you've made it a really enjoyable contribution 💜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Build castor apps as a single binary
3 participants