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
1 change: 1 addition & 0 deletions docs/local-ci-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Defaults are exported from [`script/ci-defaults.env`](../script/ci-defaults.env)
| `M2_SPINE_ISSUE_HYGIENE_GATE` | `1` | `ci-fast.sh` (`ci_run_inventory_checks`) | `script/check-m2-spine-issue-hygiene.php` — stale `m2-spine-unit` tickets ([#1819](https://github.com/PurHur/php-compiler/issues/1819), [#1808](https://github.com/PurHur/php-compiler/issues/1808)); set `0` for bulk spine PRs |
| `WAVE3_ROADMAP_SYNC_GATE` | `1` | `ci-fast.sh` (`ci_run_inventory_checks`) | `script/check-wave3-roadmap-sync.php` ([#1802](https://github.com/PurHur/php-compiler/issues/1802), [#1814](https://github.com/PurHur/php-compiler/issues/1814)); set `0` for doc-only iteration |
| `EXAMPLES_README_SYNC_GATE` | `1` | `ci-fast.sh` (`ci_run_inventory_checks`) | `script/check-examples-readme-sync.php` ([#1822](https://github.com/PurHur/php-compiler/issues/1822), [#1531](https://github.com/PurHur/php-compiler/issues/1531)); set `0` for doc-only iteration |
| `ROOT_README_SYNC_GATE` | `0` | `ci-fast.sh` (`ci_run_inventory_checks`) | `script/check-root-readme-sync.php` ([#1832](https://github.com/PurHur/php-compiler/issues/1832)); set `1` after [#48](https://github.com/PurHur/php-compiler/issues/48) / [#1525](https://github.com/PurHur/php-compiler/issues/1525) root README north-star sync |
| `SELFHOST_SPINE_COUNT_SYNC_GATE` | `1` | `ci-fast.sh` (`ci_run_inventory_checks`) | `script/check-selfhost-spine-count-sync.php` ([#1834](https://github.com/PurHur/php-compiler/issues/1834)); set `0` for bulk spine PRs |

Ladder-only env vars (not in `ci-defaults.env`): `MINIWEBAPP_LINT_GATE` (default `1` in `web-smoke.sh`), `MINIWEBAPP_AOT_BISECT_GATE` (default `0` in `miniwebapp-gates.sh` — [#879](https://github.com/PurHur/php-compiler/issues/879)).
Expand Down
75 changes: 75 additions & 0 deletions script/check-root-readme-sync.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
* Guard root README.md against stale MiniWebApp north-star wording (issue #1832).
*
* Fails when known post-#764 blocker phrases remain while examples/README.md
* documents native execute as green. Enable in CI via ROOT_README_SYNC_GATE=1
* after #48 / #1525 refresh root README (gate defaults off).
*
* Usage:
* php script/check-root-readme-sync.php
*/

$root = dirname(__DIR__);
$readme = $root.'/README.md';
$examplesReadme = $root.'/examples/README.md';

if (!is_readable($readme)) {
fwrite(STDERR, "check-root-readme-sync: missing {$readme}\n");
exit(1);
}

$body = (string) file_get_contents($readme);
$lines = preg_split("/\r\n|\n|\r/", $body) ?: [];

/** Phrases that imply #764 native execute is still open (issue #1832). */
$stale = [
'empty stdout until [#764]',
'empty stdout until #764',
'native execute blocked',
'execute blocked #764',
'blocked #764',
'native execute partial',
'execute 🚧',
];

$errors = [];
foreach ($stale as $phrase) {
if (!str_contains($body, $phrase)) {
continue;
}
foreach ($lines as $num => $line) {
if (!str_contains($line, $phrase)) {
continue;
}
$lineNo = $num + 1;
$errors[] = "stale phrase in README.md:{$lineNo}: {$phrase}";
}
}

if (preg_match('/003[^\n]{0,80}AOT execute[^\n]*🚧/u', $body)
|| preg_match('/\*\*003\*\*[^\n]{0,40}execute[^\n]*🚧/u', $body)) {
$errors[] = 'README.md: 003 AOT execute should not be 🚧 partial (post-#764; sync #1525)';
}

if (is_readable($examplesReadme)) {
$examples = (string) file_get_contents($examplesReadme);
if (str_contains($examples, 'native execute ✅') && !str_contains($body, 'native execute ✅')) {
$errors[] = 'README.md: out of sync with examples/README.md (003 native execute status)';
}
}

if ([] !== $errors) {
foreach ($errors as $err) {
fwrite(STDERR, "check-root-readme-sync: {$err}\n");
}
fwrite(STDERR, "check-root-readme-sync: FAILED (fix README.md; see #48, #1525, #1832)\n");
exit(1);
}

fwrite(STDOUT, "check-root-readme-sync: OK\n");
exit(0);
9 changes: 9 additions & 0 deletions script/ci-common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ ci_run_examples_readme_sync_check() {
"$PHP_BIN" "${PHP_OPTS[@]}" script/check-examples-readme-sync.php
}

ci_run_root_readme_sync_check() {
if [[ "${ROOT_README_SYNC_GATE:-0}" != "1" ]]; then
return 0
fi
echo "Root README sync (ROOT_README_SYNC_GATE=1, issue #1832)..."
"$PHP_BIN" "${PHP_OPTS[@]}" script/check-root-readme-sync.php
}

ci_run_selfhost_spine_count_sync_check() {
if [[ "${SELFHOST_SPINE_COUNT_SYNC_GATE:-0}" != "1" ]]; then
return 0
Expand All @@ -114,6 +122,7 @@ ci_run_inventory_checks() {
ci_run_wave3_roadmap_sync_check
ci_run_m2_spine_issue_hygiene_check
ci_run_examples_readme_sync_check
ci_run_root_readme_sync_check
ci_run_selfhost_spine_count_sync_check
}

Expand Down
1 change: 1 addition & 0 deletions script/ci-defaults.env
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export CAPABILITY_SYNTAX_CHECK="${CAPABILITY_SYNTAX_CHECK:-1}"
export M2_SPINE_ISSUE_HYGIENE_GATE="${M2_SPINE_ISSUE_HYGIENE_GATE:-1}" # default on (#1819); opt-out for bulk spine PRs
export WAVE3_ROADMAP_SYNC_GATE="${WAVE3_ROADMAP_SYNC_GATE:-1}" # default on (#1814); opt-out WAVE3_ROADMAP_SYNC_GATE=0 for doc-only iteration
export EXAMPLES_README_SYNC_GATE="${EXAMPLES_README_SYNC_GATE:-1}" # default on (#1822); opt-out EXAMPLES_README_SYNC_GATE=0 for doc-only iteration
export ROOT_README_SYNC_GATE="${ROOT_README_SYNC_GATE:-0}" # opt-in (#1832); flip to 1 with #48/#1525 README fix
export SELFHOST_SPINE_COUNT_SYNC_GATE="${SELFHOST_SPINE_COUNT_SYNC_GATE:-1}" # default on (#1834); opt-out for bulk spine PRs
1 change: 1 addition & 0 deletions script/ci-docker-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ci_docker_run() {
-e "WAVE3_ROADMAP_SYNC_GATE=${WAVE3_ROADMAP_SYNC_GATE:-1}" \
-e "M2_SPINE_ISSUE_HYGIENE_GATE=${M2_SPINE_ISSUE_HYGIENE_GATE:-1}" \
-e "EXAMPLES_README_SYNC_GATE=${EXAMPLES_README_SYNC_GATE:-1}" \
-e "ROOT_README_SYNC_GATE=${ROOT_README_SYNC_GATE:-0}" \
-e "SELFHOST_SPINE_COUNT_SYNC_GATE=${SELFHOST_SPINE_COUNT_SYNC_GATE:-1}" \
"$@"
}
28 changes: 28 additions & 0 deletions test/unit/CiScriptsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,26 @@ public function testCiDockerRunPassesExamplesReadmeSyncGateDefaultOn(): void
$this->assertStringContainsString('EXAMPLES_README_SYNC_GATE=${EXAMPLES_README_SYNC_GATE:-1}', $body);
}

public function testCiDefaultsEnvDefinesRootReadmeSyncGateOff(): void
{
$defaults = (string) file_get_contents(dirname(__DIR__, 2).'/script/ci-defaults.env');
$this->assertStringContainsString('ROOT_README_SYNC_GATE="${ROOT_README_SYNC_GATE:-0}"', $defaults);
}

public function testCiFastRunsRootReadmeSyncViaInventoryChecks(): void
{
$common = (string) file_get_contents(dirname(__DIR__, 2).'/script/ci-common.sh');
$this->assertStringContainsString('ci_run_root_readme_sync_check', $common);
$this->assertStringContainsString('check-root-readme-sync.php', $common);
$this->assertStringContainsString('ROOT_README_SYNC_GATE:-0', $common);
}

public function testCiDockerRunPassesRootReadmeSyncGateDefaultOff(): void
{
$body = (string) file_get_contents(dirname(__DIR__, 2).'/script/ci-docker-run.sh');
$this->assertStringContainsString('ROOT_README_SYNC_GATE=${ROOT_README_SYNC_GATE:-0}', $body);
}

public function testCiDefaultsEnvDefinesSelfhostSpineCountSyncGateOn(): void
{
$defaults = (string) file_get_contents(dirname(__DIR__, 2).'/script/ci-defaults.env');
Expand Down Expand Up @@ -488,6 +508,14 @@ public function testLocalCiMatrixDocumentsExamplesReadmeSyncGate(): void
$this->assertMatchesRegularExpression('/\| `EXAMPLES_README_SYNC_GATE` \| `1` \|/', $doc);
}

public function testLocalCiMatrixDocumentsRootReadmeSyncGate(): void
{
$doc = (string) file_get_contents(dirname(__DIR__, 2).'/docs/local-ci-matrix.md');
$this->assertStringContainsString('ROOT_README_SYNC_GATE', $doc);
$this->assertStringContainsString('check-root-readme-sync.php', $doc);
$this->assertMatchesRegularExpression('/\| `ROOT_README_SYNC_GATE` \| `0` \|/', $doc);
}

public function testLocalCiMatrixDocumentsSelfhostSpineCountSyncGate(): void
{
$doc = (string) file_get_contents(dirname(__DIR__, 2).'/docs/local-ci-matrix.md');
Expand Down
34 changes: 34 additions & 0 deletions test/unit/RootReadmeSyncTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace PHPCompiler;

use PHPUnit\Framework\TestCase;

/**
* Root README.md drift guard (issue #1832).
*/
final class RootReadmeSyncTest extends TestCase
{
public function testRootReadmeSyncScriptExists(): void
{
$script = dirname(__DIR__, 2).'/script/check-root-readme-sync.php';
$this->assertFileExists($script);
}

/**
* Master README still carries pre-#1525 north-star wording; guard must detect it.
*/
public function testRootReadmeSyncDetectsStaleNorthStarWordingOnMaster(): void
{
$root = dirname(__DIR__, 2);
$cmd = escapeshellarg(PHP_BINARY).' '
.escapeshellarg($root.'/script/check-root-readme-sync.php').' 2>&1';
exec($cmd, $out, $code);
$this->assertSame(1, $code, 'expected failure until #1525 fixes README.md');
$joined = implode("\n", $out);
$this->assertStringContainsString('check-root-readme-sync:', $joined);
$this->assertMatchesRegularExpression('/README\.md:\d+:/', $joined);
}
}