diff --git a/docker/openemr/8.0.0/openemr.sh b/docker/openemr/8.0.0/openemr.sh index b2aa7138..9829ca99 100644 --- a/docker/openemr/8.0.0/openemr.sh +++ b/docker/openemr/8.0.0/openemr.sh @@ -20,7 +20,7 @@ set -e # source-follower without ever running it — BusyBox ash treats `.` as a # special builtin and exits the shell on file-not-found even with `|| true`. if false; then - # shellcheck source=docker/openemr/8.0.0/env.stub + # shellcheck source=SCRIPTDIR/env.stub . /root/env.stub fi diff --git a/docker/openemr/8.0.0/ssl.sh b/docker/openemr/8.0.0/ssl.sh index 30c97299..e3843b16 100644 --- a/docker/openemr/8.0.0/ssl.sh +++ b/docker/openemr/8.0.0/ssl.sh @@ -16,7 +16,7 @@ set -e # source-follower without ever running it — BusyBox ash treats `.` as a # special builtin and exits the shell on file-not-found even with `|| true`. if false; then - # shellcheck source=docker/openemr/8.0.0/env.stub + # shellcheck source=SCRIPTDIR/env.stub . /root/env.stub fi diff --git a/tools/release/tests/SlotRotatorTest.php b/tools/release/tests/SlotRotatorTest.php index 1ddcb21a..485a1eb9 100644 --- a/tools/release/tests/SlotRotatorTest.php +++ b/tools/release/tests/SlotRotatorTest.php @@ -195,6 +195,37 @@ public function testReplacementAvoidsPartialVersionMatches(): void self::assertStringContainsString('rel-820', $after); } + public function testRotationLeavesScriptdirShellcheckDirectiveIntact(): void + { + $rotator = new SlotRotator($this->tmpDir, $this->registryPath); + + $rotator->rotate([ + 'current' => [ + 'minor' => '8.2', + 'full' => '8.2.0', + 'branch' => 'rel-820', + 'docker_dir' => '8.2.0', + ], + ]); + + $script = (string) file_get_contents($this->tmpDir . '/docker/openemr/8.0.0/openemr.sh'); + self::assertStringContainsString( + '# shellcheck source=SCRIPTDIR/env.stub', + $script, + 'self-referential SCRIPTDIR directive must survive rotation byte-for-byte', + ); + self::assertStringNotContainsString( + 'source=docker/openemr', + $script, + 'rotation must never inject a version path into a shellcheck source directive', + ); + self::assertStringContainsString( + "echo 'init for docker/openemr/8.2.0'", + $script, + 'sanity: the genuine rotating docker_dir token should have been rewritten', + ); + } + private function seedFixtures(): void { $this->writeFile('tools/release/versions.yml', <<<'YAML' @@ -230,6 +261,9 @@ private function seedFixtures(): void - path: docker/openemr/8.0.0/Dockerfile slot: current kinds: [docker_clone_branch] + - path: docker/openemr/8.0.0/openemr.sh + slot: current + kinds: [docker_dir_ref] - path: docker/openemr/8.1.0/Dockerfile slot: next kinds: [docker_arg_branch] @@ -256,6 +290,17 @@ private function seedFixtures(): void $this->writeFile('docker/openemr/8.1.0/Dockerfile', "FROM alpine:3.21\nARG OPENEMR_VERSION=rel-810\n"); $this->writeFile('docker/openemr/8.1.1/Dockerfile', "FROM alpine:3.21\nARG OPENEMR_VERSION=master\n"); + // In-container init script for the current slot. It carries a rotating + // docker_dir token (the path in the echo line) alongside a + // self-referential `SCRIPTDIR` shellcheck directive that must never be + // rewritten. + $this->writeFile( + 'docker/openemr/8.0.0/openemr.sh', + "#!/bin/sh\nset -e\n" + . "# shellcheck source=SCRIPTDIR/env.stub\n. /root/env.stub\n" + . "echo 'init for docker/openemr/8.0.0'\n", + ); + $this->writeFile( 'docker/openemr/OVERVIEW.md', "| 8.0.0 | latest |\n| 8.1.0 | next |\n| 8.1.1 | dev |\n", diff --git a/tools/release/versions.yml b/tools/release/versions.yml index 67030411..bff5101e 100644 --- a/tools/release/versions.yml +++ b/tools/release/versions.yml @@ -122,17 +122,6 @@ files: slot: all kinds: [dependabot_directory] - # In-container init scripts; reference their own dir as shellcheck source - # comments, so they rotate with the slot's docker_dir. Only the 8.0.0/*.sh - # files currently have these refs; the next/dev variants have no path - # comments and will be picked up by the linter only if added later. - - path: docker/openemr/8.0.0/openemr.sh - slot: current - kinds: [shellcheck_source] - - path: docker/openemr/8.0.0/ssl.sh - slot: current - kinds: [shellcheck_source] - # Container-benchmarking docs reference the next-slot version as defaults. - path: utilities/container_benchmarking/README.md slot: next