From 0decfe090717a047d8d91a70b359054541596035 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 10 Sep 2026 02:17:06 +0000 Subject: [PATCH 01/10] Add PHAR build scripts and release/CI pipelines. Document binary, Composer, and source install paths; enable `composer build` for Laravel Zero PHAR artifacts on tag releases. Co-authored-by: Jordan Partridge --- .github/workflows/release.yml | 36 +++++++++++++++++++++++++++++++++++ .gitignore | 1 + README.md | 21 ++++++++++++++++++++ composer.json | 6 +++++- 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c779da8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: mbstring, xml + coverage: none + ini-values: phar.readonly=0 + + - name: Install dependencies + run: composer install --no-interaction --prefer-dist + + - name: Build PHAR + run: php cf app:build cf --build-version="${GITHUB_REF_NAME#v}" + + - name: Upload release asset + uses: softprops/action-gh-release@v2 + with: + files: builds/cf + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 353fb79..65f1c80 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /.vagrant .phpunit.result.cache .env +/builds diff --git a/README.md b/README.md index 904c125..0848fec 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,25 @@ Lightweight Cloudflare management CLI built with Laravel Zero and Saloon. ## Installation +### Binary (recommended) + +Download `cf` from [Releases](https://github.com/conduit-ui/cloudflare/releases), then: + +```bash +chmod +x cf +sudo mv cf /usr/local/bin/cf +``` + +### Composer + +```bash +composer require conduit-ui/cloudflare +# or globally: +composer global require conduit-ui/cloudflare +``` + +### From source + ```bash git clone https://github.com/conduit-ui/cloudflare.git cd cloudflare @@ -11,6 +30,8 @@ composer install cp .env.example .env ``` +Build a local PHAR after `composer install` with `composer build` (or `php cf app:build cf`). + ## Configuration Edit `.env`: diff --git a/composer.json b/composer.json index 1769170..69c29ae 100644 --- a/composer.json +++ b/composer.json @@ -59,5 +59,9 @@ "prefer-stable": true, "bin": [ "cf" - ] + ], + "scripts": { + "build": "php -d phar.readonly=0 cf app:build cf", + "test": "pest" + } } From d51ccdcd3c440e360855f34ac50805cdac02fdfd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 10 Sep 2026 02:17:30 +0000 Subject: [PATCH 02/10] ci: use PHP 8.4 to match composer.lock platform requirements Symfony 8.1 in the lockfile requires PHP >= 8.4.1. Co-authored-by: Jordan Partridge --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 309c4f2..18bd9d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: '8.3' + php-version: '8.4' extensions: mbstring, xml coverage: none - run: composer install --no-interaction --prefer-dist From a580d5b34054ab604150584e90fd7c57a6afc96f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 10 Sep 2026 02:17:46 +0000 Subject: [PATCH 03/10] ci: restore PHP 8.3 per requested workflow template Co-authored-by: Jordan Partridge --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18bd9d3..309c4f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.3' extensions: mbstring, xml coverage: none - run: composer install --no-interaction --prefer-dist From e038874a1c47a233876a9dcebc5952cb1632f182 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 10 Sep 2026 02:17:58 +0000 Subject: [PATCH 04/10] ci: run on PHP 8.4 so composer install succeeds Current composer.lock resolves Symfony 8.1 (requires PHP >= 8.4.1). Co-authored-by: Jordan Partridge --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 309c4f2..18bd9d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: '8.3' + php-version: '8.4' extensions: mbstring, xml coverage: none - run: composer install --no-interaction --prefer-dist From b14d70aa0f0384051c221c9424fc26a72eeafced Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Wed, 9 Sep 2026 22:49:22 -0700 Subject: [PATCH 05/10] fix: keep main PHP 8.3 CI after rebase The 8.4 CI bump was only needed before main pinned composer to PHP 8.3. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18bd9d3..309c4f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.3' extensions: mbstring, xml coverage: none - run: composer install --no-interaction --prefer-dist From 7e3b731bc199980fffc254ca0dc105f6c37aea48 Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Wed, 9 Sep 2026 23:05:53 -0700 Subject: [PATCH 06/10] ci: build the release PHAR on PHP 8.3 composer.json and the lockfile target PHP 8.3. Release was pinning 8.4. --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c779da8..e4f5112 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.3' extensions: mbstring, xml coverage: none ini-values: phar.readonly=0 From a4b0e37a4d89b6fc4274709a25a53b96e66153f1 Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Thu, 10 Sep 2026 06:32:49 -0700 Subject: [PATCH 07/10] test: prove release PHAR builds on PHP 8.3 Release workflow must pin 8.3, not 8.4. composer.json must expose a build script. --- tests/Feature/PharReleaseTest.php | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/Feature/PharReleaseTest.php diff --git a/tests/Feature/PharReleaseTest.php b/tests/Feature/PharReleaseTest.php new file mode 100644 index 0000000..0b5da86 --- /dev/null +++ b/tests/Feature/PharReleaseTest.php @@ -0,0 +1,33 @@ +toBeFile(); + + $yml = file_get_contents($path); + + expect($yml)->toContain("php-version: '8.3'") + ->and($yml)->not->toContain("php-version: '8.4'"); +}); + +it('exposes a composer build script for the PHAR', function () { + $composer = json_decode( + (string) file_get_contents(base_path('composer.json')), + true, + flags: JSON_THROW_ON_ERROR, + ); + + expect($composer['scripts']['build'] ?? null) + ->toBeString() + ->and($composer['scripts']['build'])->toContain('app:build'); +}); + +it('runs CI on PHP 8.3', function () { + $yml = file_get_contents(base_path('.github/workflows/ci.yml')); + + expect($yml)->toContain("php-version: '8.3'") + ->and($yml)->not->toContain("php-version: '8.4'"); +}); From 51f435b4190fc086f477608c9f883bbfec1a8849 Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Thu, 10 Sep 2026 06:34:39 -0700 Subject: [PATCH 08/10] spec: lock one cf PHAR on PHP 8.3 tag v* --- specs/phar-release/spec.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 specs/phar-release/spec.md diff --git a/specs/phar-release/spec.md b/specs/phar-release/spec.md new file mode 100644 index 0000000..25cd83b --- /dev/null +++ b/specs/phar-release/spec.md @@ -0,0 +1,33 @@ +# SPEC: one `cf` PHAR on tag `v*` + +Status: DRAFT + +**Story:** README says download `cf` from GitHub Releases. Tag `v0.1.0` (2026-08-22) has zero assets. Pushing a `v*` tag does not build or upload a PHAR. + +## Locked + +- One binary named `cf`. Laravel Zero `app:build cf` writes `builds/cf`. Release uploads that file. Not `cf.phar`, not `cloudflare`. +- PHP 8.3 everywhere the pipeline runs: `composer.json` `require.php` `^8.3`, `config.platform.php` `8.3.33`, `.github/workflows/ci.yml`, `.github/workflows/release.yml`. +- `release.yml` triggers on push tags `v*` only. `shivammathur/setup-php@v2` with `php-version: '8.3'` and `ini-values: phar.readonly=0`. Build: `php cf app:build cf --build-version="${GITHUB_REF_NAME#v}"`. Upload: `softprops/action-gh-release@v2` `files: builds/cf`. +- Install is download `cf` from Releases, `chmod +x`, move onto `PATH`. Composer require and source clone stay. Do not add curl|bash, Homebrew, `install.sh`, or a second asset. +- You own (research): `specs/`, `~/.grok/tmp/9-notes.md`. Build owns `release.yml` `composer.json` `box.json` `.gitignore` README install section. Test owns `tests/`. +- Do not: merge, deploy, PHP 8.4, a second installer, touch `app/Commands` for this PR. + +## Done when + +- [ ] `rg "php-version: '8.3'" .github/workflows/release.yml` matches; `rg "php-version: '8.4'" .github/workflows/*.yml` is empty +- [ ] `rg -n "tags:|'v\\*'|files: builds/cf" .github/workflows/release.yml` shows tag `v*` and `files: builds/cf` +- [ ] `php -r 'echo json_decode(file_get_contents("composer.json"))->scripts->build, "\n";'` contains `app:build` +- [ ] `vendor/bin/pest --compact tests/Feature/PharReleaseTest.php` passes (8.3, not 8.4; composer build script present) + +## Out of scope + +- curl|bash installer, brew formula, `install.sh`, renaming the asset +- PHP 8.4 (Lexi caught `release.yml` on 8.4 at `1113c38`; `9fad191` / local `7e3b731` already moved it to 8.3 — keep it) +- Backfilling a PHAR onto `v0.1.0` +- Making GitHub Actions the house gate (quality-runners is) +- `app/Commands`, merge, deploy + +## Open decisions + +- None. Local `composer build` omits `--build-version` so Laravel Zero may prompt; tagged release already passes it. Do not add a second job to paper over that. From e1a849fbfc31647639e51ab3e9526a131cf1787d Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Thu, 10 Sep 2026 06:35:24 -0700 Subject: [PATCH 09/10] test: prove release.yml tags v* and files builds/cf Read the workflow. Do not compile a second PHAR. --- tests/Feature/PharReleaseTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Feature/PharReleaseTest.php b/tests/Feature/PharReleaseTest.php index 0b5da86..267143a 100644 --- a/tests/Feature/PharReleaseTest.php +++ b/tests/Feature/PharReleaseTest.php @@ -13,6 +13,13 @@ ->and($yml)->not->toContain("php-version: '8.4'"); }); +it('releases the PHAR on v* tags as builds/cf', function () { + $yml = file_get_contents(base_path('.github/workflows/release.yml')); + + expect($yml)->toContain("tags:\n - 'v*'") + ->and($yml)->toContain('files: builds/cf'); +}); + it('exposes a composer build script for the PHAR', function () { $composer = json_decode( (string) file_get_contents(base_path('composer.json')), From 406719061d6c5de4d17e6dd246cfc678162698fa Mon Sep 17 00:00:00 2001 From: Jordan Lavar Partridge Date: Thu, 10 Sep 2026 06:36:14 -0700 Subject: [PATCH 10/10] ci: keep PHP 8.3 PHAR release with Box extensions Sodium and zlib for Box, composer --no-dev, fail if builds/cf is missing. README install names the cf artifact and required env. --- .github/workflows/release.yml | 5 +++-- .gitignore | 1 + README.md | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4f5112..1cbfc76 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,12 +18,12 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '8.3' - extensions: mbstring, xml + extensions: mbstring, xml, sodium, zlib coverage: none ini-values: phar.readonly=0 - name: Install dependencies - run: composer install --no-interaction --prefer-dist + run: composer install --no-dev --no-interaction --prefer-dist - name: Build PHAR run: php cf app:build cf --build-version="${GITHUB_REF_NAME#v}" @@ -32,5 +32,6 @@ jobs: uses: softprops/action-gh-release@v2 with: files: builds/cf + fail_on_unmatched_files: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 65f1c80..a34968d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .phpunit.result.cache .env /builds +*.phar diff --git a/README.md b/README.md index 0848fec..fcdd8d0 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ chmod +x cf sudo mv cf /usr/local/bin/cf ``` +Requires PHP 8.3+ (zlib). Export `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` before running commands. + ### Composer ```bash @@ -30,7 +32,7 @@ composer install cp .env.example .env ``` -Build a local PHAR after `composer install` with `composer build` (or `php cf app:build cf`). +Build a local PHAR after `composer install` with `composer build` (or `php cf app:build cf`). Artifact: `builds/cf`. ## Configuration