From 840af39655ff562d26bf6e53b472a03ab08f09b7 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 11:53:09 +0800 Subject: [PATCH 01/21] push to registry if main branch --- .github/workflows/build.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab38836..5a437ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,6 +54,9 @@ jobs: fail-fast: false matrix: variant: ${{ fromJson(needs.changes.outputs.variants) }} + permissions: + contents: read + packages: write steps: - name: Checkout code uses: actions/checkout@v4 @@ -94,3 +97,15 @@ jobs: - name: Test run: make test-setup test-${{ matrix.variant }} + + - name: Login to GitHub Container Registry + if: github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push to GitHub Container Registry + if: github.ref == 'refs/heads/main' + run: make push-${{ matrix.variant }} From 1997c710b1a47e5521aed524daffeedae07e2b9a Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 11:55:19 +0800 Subject: [PATCH 02/21] temporary test branch --- .github/workflows/build.yml | 4 ++-- php84-debian12/.trigger-ci | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 php84-debian12/.trigger-ci diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5a437ff..884862c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,7 +99,7 @@ jobs: run: make test-setup test-${{ matrix.variant }} - name: Login to GitHub Container Registry - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/ci-release' uses: docker/login-action@v3 with: registry: ghcr.io @@ -107,5 +107,5 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push to GitHub Container Registry - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/ci-release' run: make push-${{ matrix.variant }} diff --git a/php84-debian12/.trigger-ci b/php84-debian12/.trigger-ci new file mode 100644 index 0000000..e69de29 From bf190b4ab52c388c2fe2b46e8c3c6bfd47e30e72 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 12:02:41 +0800 Subject: [PATCH 03/21] Revert "temporary test branch" This reverts commit 1997c710b1a47e5521aed524daffeedae07e2b9a. --- .github/workflows/build.yml | 4 ++-- php84-debian12/.trigger-ci | 0 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 php84-debian12/.trigger-ci diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 884862c..5a437ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,7 +99,7 @@ jobs: run: make test-setup test-${{ matrix.variant }} - name: Login to GitHub Container Registry - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/ci-release' + if: github.ref == 'refs/heads/main' uses: docker/login-action@v3 with: registry: ghcr.io @@ -107,5 +107,5 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push to GitHub Container Registry - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/ci-release' + if: github.ref == 'refs/heads/main' run: make push-${{ matrix.variant }} diff --git a/php84-debian12/.trigger-ci b/php84-debian12/.trigger-ci deleted file mode 100644 index e69de29..0000000 From c94c5f8e1b4ee0a4cc32be9e6a5d9e6bc2d51371 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 12:37:32 +0800 Subject: [PATCH 04/21] extract docker variables --- Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 38752a0..8cfa82d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ OBJECTS = php81 php82 php83 php84 VARIANTS = $(addsuffix -debian11,$(OBJECTS)) $(addsuffix -debian12,$(OBJECTS)) +DOCKER_REGISTRY ?= ghcr.io +DOCKER_IMAGE ?= dew-serverless/php DOCKER_BUILD_EXTRA ?= .PHONY: build export publish clean @@ -8,8 +10,7 @@ build-%: BUILD_ARGS="$(shell awk '/^[a-zA-Z0-9]+ *=/ { printf "--build-arg %s_VERSION=%s ", toupper($$1), $$3 }' "$*/dependencies.ini" | xargs)" && \ docker buildx build $$BUILD_ARGS $(DOCKER_BUILD_EXTRA) \ --load \ - -t dew/$* \ - -t ghcr.io/dew-serverless/php:$(subst php,,$*) \ + -t $(DOCKER_BUILD_EXTRA)/$(DOCKER_IMAGE):$(subst php,,$*) \ . build: $(addprefix build-,$(VARIANTS)) @@ -25,8 +26,10 @@ test-%: test: test-setup $(addprefix test-,$(VARIANTS)) export/%: - CID=$$(docker create dew/$*) && docker cp $$CID:/opt ./export/$* && docker rm $$CID - cd export/$*; zip -r ../$*.zip . + CID=$$(docker create $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(subst php,,$*)) && \ + docker cp $$CID:/opt ./export/$* && \ + docker rm $$CID && \ + cd export/$* && zip -r ../$*.zip . export: $(addprefix export/,$(VARIANTS)) @@ -36,7 +39,7 @@ publish-%: export/% publish: $(addprefix publish-,$(VARIANTS)) push-%: build-% - docker push ghcr.io/dew-serverless/php:$(subst php,,$*) + docker push $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(subst php,,$*) push: $(addprefix push-,$(VARIANTS)) From 8b6bdaa94d2beb9c958de5657896c948e166f8b9 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 13:34:08 +0800 Subject: [PATCH 05/21] publish: update acs sdk --- publish/composer.json | 2 +- publish/composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/publish/composer.json b/publish/composer.json index f015712..b4da272 100644 --- a/publish/composer.json +++ b/publish/composer.json @@ -1,6 +1,6 @@ { "require": { - "dew-serverless/acs-sdk-php": "^0.7.0", + "dew-serverless/acs-sdk-php": "^0.9.0", "php-http/guzzle7-adapter": "^1.1", "guzzlehttp/guzzle": "^7.0" }, diff --git a/publish/composer.lock b/publish/composer.lock index ccf530b..2808604 100644 --- a/publish/composer.lock +++ b/publish/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "52f2a9d391668a15e3d3df43f254724b", + "content-hash": "ac3e80ea54ba793f9a6b28a59083dda0", "packages": [ { "name": "clue/stream-filter", @@ -74,16 +74,16 @@ }, { "name": "dew-serverless/acs-sdk-php", - "version": "v0.7.0+20241130", + "version": "v0.9.0+20250818", "source": { "type": "git", "url": "https://github.com/dew-serverless/acs-sdk-php.git", - "reference": "3572e254b6b6f1021ed8c060df4262bad288393b" + "reference": "6f27f9a531fe191312072df483c88315faeb3a59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dew-serverless/acs-sdk-php/zipball/3572e254b6b6f1021ed8c060df4262bad288393b", - "reference": "3572e254b6b6f1021ed8c060df4262bad288393b", + "url": "https://api.github.com/repos/dew-serverless/acs-sdk-php/zipball/6f27f9a531fe191312072df483c88315faeb3a59", + "reference": "6f27f9a531fe191312072df483c88315faeb3a59", "shasum": "" }, "require": { @@ -130,9 +130,9 @@ "description": "Unofficial Alibaba Cloud PHP SDK.", "support": { "issues": "https://github.com/dew-serverless/acs-sdk-php/issues", - "source": "https://github.com/dew-serverless/acs-sdk-php/tree/v0.7.0+20241130" + "source": "https://github.com/dew-serverless/acs-sdk-php/tree/v0.9.0+20250818" }, - "time": "2024-11-30T13:52:28+00:00" + "time": "2025-08-18T04:02:07+00:00" }, { "name": "guzzlehttp/guzzle", From dc0142e4182f79f64008326633cd9a91d12e3f69 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 13:35:09 +0800 Subject: [PATCH 06/21] publish: support debian 12 --- publish/publish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/publish/publish.php b/publish/publish.php index 7780736..359f1d7 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -173,6 +173,7 @@ function layerEnsureIsPublic(FcClient $client, string $runtime): void function getRuntimeFromLayerName(string $layerName): string { return match (true) { + str_ends_with($layerName, '-debian12') => 'custom.debian12', str_ends_with($layerName, '-debian11') => 'custom.debian11', str_ends_with($layerName, '-debian10') => 'custom.debian10', default => 'custom', From dc435ca2be8e4e8444cf85b3b32681809a4281a5 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 13:53:39 +0800 Subject: [PATCH 07/21] publish: publish layer with checksum --- publish/publish.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/publish/publish.php b/publish/publish.php index 359f1d7..66bcb93 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -141,7 +141,7 @@ function layerExists(FcClient $client, string $runtime, string $checksum): bool return true; } -function layerPublish(FcClient $client, string $runtime, string $bucket, string $object): void +function layerPublish(FcClient $client, string $runtime, string $bucket, string $object, string $checksum): void { $client->createLayerVersion([ 'layerName' => $runtime, @@ -149,6 +149,7 @@ function layerPublish(FcClient $client, string $runtime, string $bucket, string 'code' => [ 'ossBucketName' => $bucket, 'ossObjectName' => $object, + 'checksum' => $checksum, ], 'compatibleRuntime' => [ getRuntimeFromLayerName($runtime), @@ -206,7 +207,7 @@ function getRuntimeFromLayerName(string $layerName): string step("Release layer to region {$region} (exists)"); } else { step("Release layer to region {$region}"); - layerPublish($fc, $runtime, $bucketName, $objectName); + layerPublish($fc, $runtime, $bucketName, $objectName, $checksum); } step("Ensure layer is public in {$region}"); From 0aa049899b93361d4cdceed14646b9d5abe058b5 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:07:45 +0800 Subject: [PATCH 08/21] publish: rename variable --- publish/publish.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/publish/publish.php b/publish/publish.php index 66bcb93..4c8a8cd 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -183,7 +183,7 @@ function getRuntimeFromLayerName(string $layerName): string step("Process {$runtime} runtime"); -$checksum = fileChecksum($runtimePath); +$crc64 = fileChecksum($runtimePath); foreach ($regions as $region) { $bucketName = $bucket.'-'.$region; @@ -203,11 +203,11 @@ function getRuntimeFromLayerName(string $layerName): string // is about 50MiB, we force garbage collection and free up memory. gc_collect_cycles(); - if (layerExists($fc, $runtime, $checksum)) { + if (layerExists($fc, $runtime, $crc64)) { step("Release layer to region {$region} (exists)"); } else { step("Release layer to region {$region}"); - layerPublish($fc, $runtime, $bucketName, $objectName, $checksum); + layerPublish($fc, $runtime, $bucketName, $objectName, $crc64); } step("Ensure layer is public in {$region}"); From 0cfadb2db87669ba8bfe3ae8ab735954940de725 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:27:46 +0800 Subject: [PATCH 09/21] publish: verify the integrity while uploading --- publish/publish.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/publish/publish.php b/publish/publish.php index 4c8a8cd..cbea789 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -91,13 +91,13 @@ function createFcClient(string $key, string $secret, string $region): FcClient ]); } -function fileExists(OssClient $client, string $bucket, string $object, string $filename): bool +function fileExists(OssClient $client, string $bucket, string $object, string $filename, string $md5): bool { try { $client->headObject([ 'bucket' => $bucket, 'key' => $object, - 'If-Match' => strtoupper(md5_file($filename)), + 'If-Match' => strtoupper($md5), ]); return true; @@ -106,12 +106,15 @@ function fileExists(OssClient $client, string $bucket, string $object, string $f } } -function fileUpload(OssClient $client, string $bucket, string $object, string $filename): void +function fileUpload(OssClient $client, string $bucket, string $object, string $filename, string $md5): void { $client->putObject([ 'bucket' => $bucket, 'key' => $object, 'body' => file_get_contents($filename), + '@headers' => [ + 'Content-MD5' => $md5, + ], ]); } @@ -184,6 +187,8 @@ function getRuntimeFromLayerName(string $layerName): string step("Process {$runtime} runtime"); $crc64 = fileChecksum($runtimePath); +$md5 = md5_file($runtimePath); +$md5Base64 = base64_encode(md5_file($runtimePath, true)); foreach ($regions as $region) { $bucketName = $bucket.'-'.$region; @@ -191,11 +196,11 @@ function getRuntimeFromLayerName(string $layerName): string $oss = createOssClient($accessKeyId, $accessKeySecret, $region); $fc = createFcClient($accessKeyId, $accessKeySecret, $region); - if (fileExists($oss, $bucketName, $objectName, $runtimePath)) { + if (fileExists($oss, $bucketName, $objectName, $runtimePath, $md5)) { step("Upload layer to region {$region} (exists)"); } else { step("Upload layer to region {$region}"); - fileUpload($oss, $bucketName, $objectName, $runtimePath); + fileUpload($oss, $bucketName, $objectName, $runtimePath, $md5Base64); } // Instead of partially uploading the layer package one step at a time, From 33aa0d23e6e2d4225ec96bc333ebf9fb30f08365 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:49:19 +0800 Subject: [PATCH 10/21] publish: include the release version in the object name --- Makefile | 2 +- publish/publish.php | 65 +++++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 8cfa82d..78bf82d 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ export/%: export: $(addprefix export/,$(VARIANTS)) publish-%: export/% - php publish/publish.php $* + php publish/publish.php $* $(RELEASE) publish: $(addprefix publish-,$(VARIANTS)) diff --git a/publish/publish.php b/publish/publish.php index cbea789..112092e 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -36,9 +36,10 @@ $accessKeyId = getenv('ACS_ACCESS_KEY_ID'); $accessKeySecret = getenv('ACS_ACCESS_KEY_SECRET'); -$runtime = $argv[1] ?? null; -$runtimePath = __DIR__.'/../export/'.$runtime.'.zip'; -$objectName = $runtime.'.zip'; +$variant = $argv[1] ?? ''; +$release = $argv[2] ?? ''; +$filename = __DIR__.'/../export/'.$variant.'.zip'; +$objectName = sprintf('%s-%s.zip', $variant, normalizeRelease($release)); if (! $bucket) { fatal('Expect the base name of OSS bucket'); @@ -48,12 +49,16 @@ fatal('Expect ACS credentials'); } -if (! $runtime) { - fatal('Expect runtime name, e.g. php84-debian11'); +if ($variant === '') { + fatal('Expect a variant name, e.g. php84-debian11'); } -if (! file_exists($runtimePath)) { - fatal('The runtime layer package is missing'); +if ($release === '') { + fatal('Expect a release version, e.g. v2025.1'); +} + +if (! file_exists($filename)) { + fatal('The runtime package is missing'); } function fatal(string $message): void @@ -68,6 +73,20 @@ function step(string $message): void printf('[-] %s'.PHP_EOL, $message); } +function normalizeRelease(string $release): string +{ + // Ensure the release has the leading 'v' + $normalized = str_starts_with($release, 'v') ? $release : 'v'.$release; + + // Then, we get rid of the leading 'v' + $normalized = substr($normalized, 1); + + // Replace the dot with an underscore + $normalized = str_replace('.', '_', $normalized); + + return $normalized; +} + function createOssClient(string $key, string $secret, string $region): OssClient { return new OssClient([ @@ -125,10 +144,10 @@ function fileChecksum(string $filename): int return Crc64::make($contents); } -function layerExists(FcClient $client, string $runtime, string $checksum): bool +function layerExists(FcClient $client, string $variant, string $checksum): bool { $data = $client->listLayers([ - 'prefix' => $runtime, + 'prefix' => $variant, 'limit' => 1, 'official' => 'false', // A type of string by API definition ])->getDecodedData(); @@ -144,10 +163,10 @@ function layerExists(FcClient $client, string $runtime, string $checksum): bool return true; } -function layerPublish(FcClient $client, string $runtime, string $bucket, string $object, string $checksum): void +function layerPublish(FcClient $client, string $variant, string $bucket, string $object, string $checksum): void { $client->createLayerVersion([ - 'layerName' => $runtime, + 'layerName' => $variant, 'body' => [ 'code' => [ 'ossBucketName' => $bucket, @@ -155,17 +174,17 @@ function layerPublish(FcClient $client, string $runtime, string $bucket, string 'checksum' => $checksum, ], 'compatibleRuntime' => [ - getRuntimeFromLayerName($runtime), + getRuntimeFromLayerName($variant), ], 'license' => 'MIT', ], ]); } -function layerEnsureIsPublic(FcClient $client, string $runtime): void +function layerEnsureIsPublic(FcClient $client, string $variant): void { $client->putLayerACL([ - 'layerName' => $runtime, + 'layerName' => $variant, // Allowed values: // '0': private (default) @@ -184,11 +203,11 @@ function getRuntimeFromLayerName(string $layerName): string }; } -step("Process {$runtime} runtime"); +step("Process {$variant} runtime"); -$crc64 = fileChecksum($runtimePath); -$md5 = md5_file($runtimePath); -$md5Base64 = base64_encode(md5_file($runtimePath, true)); +$crc64 = fileChecksum($filename); +$md5 = md5_file($filename); +$md5Base64 = base64_encode(md5_file($filename, true)); foreach ($regions as $region) { $bucketName = $bucket.'-'.$region; @@ -196,11 +215,11 @@ function getRuntimeFromLayerName(string $layerName): string $oss = createOssClient($accessKeyId, $accessKeySecret, $region); $fc = createFcClient($accessKeyId, $accessKeySecret, $region); - if (fileExists($oss, $bucketName, $objectName, $runtimePath, $md5)) { + if (fileExists($oss, $bucketName, $objectName, $filename, $md5)) { step("Upload layer to region {$region} (exists)"); } else { step("Upload layer to region {$region}"); - fileUpload($oss, $bucketName, $objectName, $runtimePath, $md5Base64); + fileUpload($oss, $bucketName, $objectName, $filename, $md5Base64); } // Instead of partially uploading the layer package one step at a time, @@ -208,15 +227,15 @@ function getRuntimeFromLayerName(string $layerName): string // is about 50MiB, we force garbage collection and free up memory. gc_collect_cycles(); - if (layerExists($fc, $runtime, $crc64)) { + if (layerExists($fc, $variant, $crc64)) { step("Release layer to region {$region} (exists)"); } else { step("Release layer to region {$region}"); - layerPublish($fc, $runtime, $bucketName, $objectName, $crc64); + layerPublish($fc, $variant, $bucketName, $objectName, $crc64); } step("Ensure layer is public in {$region}"); - layerEnsureIsPublic($fc, $runtime); + layerEnsureIsPublic($fc, $variant); } step('Publish is done'); From 39941bcbcc1342a7cd4dbd4eb4ea349351b74061 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:51:52 +0800 Subject: [PATCH 11/21] publish: support me-central-1 region --- publish/publish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/publish/publish.php b/publish/publish.php index 112092e..abd8bf5 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -29,6 +29,7 @@ 'eu-west-1', 'us-east-1', 'us-west-1', + 'me-central-1', ]; $bucket = getenv('OSS_BUCKET'); From dcfbf2435a0149edb702ccf422928ed14324f862 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:53:33 +0800 Subject: [PATCH 12/21] publish: support cn-wulanchabu region --- publish/publish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/publish/publish.php b/publish/publish.php index abd8bf5..a4c7a6a 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -24,6 +24,7 @@ 'cn-qingdao', 'cn-shanghai', 'cn-shenzhen', + 'cn-wulanchabu', 'cn-zhangjiakou', 'eu-central-1', 'eu-west-1', From 3c8510b92fbc0c89a542361db0d216ec2e0f73f1 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 14:55:59 +0800 Subject: [PATCH 13/21] publish: align the order with the documentation --- publish/publish.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/publish/publish.php b/publish/publish.php index a4c7a6a..d4069d9 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -10,22 +10,22 @@ // See: https://www.alibabacloud.com/help/zh/functioncompute/fc-3-0/product-overview/supported-regions // See: https://www.alibabacloud.com/help/en/functioncompute/fc-3-0/product-overview/supported-regions $regions = [ - 'ap-northeast-1', - 'ap-northeast-2', + 'cn-hangzhou', + 'cn-shanghai', + 'cn-qingdao', + 'cn-beijing', + 'cn-zhangjiakou', + 'cn-huhehaote', + 'cn-wulanchabu', + 'cn-shenzhen', + 'cn-chengdu', + 'cn-hongkong', 'ap-southeast-1', 'ap-southeast-3', 'ap-southeast-5', 'ap-southeast-7', - 'cn-beijing', - 'cn-chengdu', - 'cn-hangzhou', - 'cn-hongkong', - 'cn-huhehaote', - 'cn-qingdao', - 'cn-shanghai', - 'cn-shenzhen', - 'cn-wulanchabu', - 'cn-zhangjiakou', + 'ap-northeast-1', + 'ap-northeast-2', 'eu-central-1', 'eu-west-1', 'us-east-1', From b3663ffc56d84fe7e6120e7685a98b26c6ecee53 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 22:43:18 +0800 Subject: [PATCH 14/21] release workflow --- .github/filters.yml | 31 ++++++++++ .github/workflows/release.yml | 106 ++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 .github/filters.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/filters.yml b/.github/filters.yml new file mode 100644 index 0000000..62d34e8 --- /dev/null +++ b/.github/filters.yml @@ -0,0 +1,31 @@ +php84-debian12: + - 'php84-debian12/**' + - 'Dockerfile' + +php84-debian11: + - 'php84-debian11/**' + - 'Dockerfile' + +php83-debian12: + - 'php83-debian12/**' + - 'Dockerfile' + +php83-debian11: + - 'php83-debian11/**' + - 'Dockerfile' + +php82-debian12: + - 'php82-debian12/**' + - 'Dockerfile' + +php82-debian11: + - 'php82-debian11/**' + - 'Dockerfile' + +php81-debian12: + - 'php81-debian12/**' + - 'Dockerfile' + +php81-debian11: + - 'php81-debian11/**' + - 'Dockerfile' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..abfda34 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,106 @@ +name: Release + +on: + release: + types: [created] + +jobs: + changes: + name: Detect changes since last release + runs-on: ubuntu-latest + outputs: + variants: ${{ steps.filter.outputs.changes }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Retrieve the previous release version + id: previous_release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Attempt to get the tag of the second-to-last release + PREVIOUS_TAG=$(gh release list --limit 2 --json tagName | jq -r '. | select(length > 1) | .[1].tagName') + + if [[ -z "$PREVIOUS_TAG" ]]; then + echo "No previous release found. Falling back to the first commit." + REF=$(git rev-list --max-parents=0 HEAD) + else + echo "Found previous release: $PREVIOUS_TAG" + REF=$PREVIOUS_TAG + fi + + echo "The reference point is: $REF" + echo "ref=$REF" >> $GITHUB_OUTPUT + + - name: Detect changed variants + uses: dorny/paths-filter@v3 + id: filter + with: + filters: .github/filters.yml + base: ${{ steps.previous_release.outputs.ref }} + + release: + name: Release ${{ matrix.variant }} + needs: changes + runs-on: ubuntu-latest + permissions: + contents: write + strategy: + fail-fast: false + matrix: + variant: ${{ fromJson(needs.changes.outputs.variants) }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + + - name: Get composer cache directory + id: composer-cache + working-directory: ./publish + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('publish/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + working-directory: ./publish + run: composer install --prefer-dist + + - name: Pull image from registry + run: | + TAG=$(echo "${{ matrix.variant }}" | sed 's/^php//') + docker pull ghcr.io/${{ github.repository_owner }}/php:$TAG + + - name: Export artifact + env: + DOCKER_REGISTRY: ghcr.io + DOCKER_IMAGE: ${{ github.repository_owner }}/php + run: make export/${{ matrix.variant }} + + - name: Upload release asset + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload ${{ github.event.release.tag_name }} \ + ./export/${{ matrix.variant }}.zip \ + --clobber + + - name: Publish to Alibaba Cloud + env: + OSS_BUCKET: ${{ secrets.OSS_BUCKET }} + ACS_ACCESS_KEY_ID: ${{ secrets.ACS_ACCESS_KEY_ID }} + ACS_ACCESS_KEY_SECRET: ${{ secrets.ACS_ACCESS_KEY_SECRET }} + run: | + RELEASE="${{ github.event.release.tag_name }}" \ + make publish-${{ matrix.variant }} From 9ca02ec2e800b6479e1bc08cf3a6a577556a53c0 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 23 Aug 2025 22:51:09 +0800 Subject: [PATCH 15/21] fix when variants is empty --- .github/workflows/build.yml | 1 + .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5a437ff..775d7e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,6 +47,7 @@ jobs: needs: changes name: Build ${{ matrix.variant }} image runs-on: ubuntu-latest + if: needs.changes.outputs.variants != '[]' concurrency: group: build-${{ matrix.variant }} cancel-in-progress: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index abfda34..ee13b7d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,6 +46,7 @@ jobs: name: Release ${{ matrix.variant }} needs: changes runs-on: ubuntu-latest + if: needs.changes.outputs.variants != '[]' permissions: contents: write strategy: From 0e93ebbb31d0594c0e00c09a3938f0bdba0b5c59 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sun, 24 Aug 2025 20:49:57 +0800 Subject: [PATCH 16/21] use external filters --- .github/workflows/build.yml | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 775d7e5..534464f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,31 +17,7 @@ jobs: - uses: dorny/paths-filter@v3 id: filter with: - filters: | - php84-debian12: - - 'php84-debian12/**' - - 'Dockerfile' - php84-debian11: - - 'php84-debian11/**' - - 'Dockerfile' - php83-debian12: - - 'php83-debian12/**' - - 'Dockerfile' - php83-debian11: - - 'php83-debian11/**' - - 'Dockerfile' - php82-debian12: - - 'php82-debian12/**' - - 'Dockerfile' - php82-debian11: - - 'php82-debian11/**' - - 'Dockerfile' - php81-debian12: - - 'php81-debian12/**' - - 'Dockerfile' - php81-debian11: - - 'php81-debian11/**' - - 'Dockerfile' + filters: .github/filters.yml build: needs: changes From f663bbadbffac3c2acead722543f7775447d8791 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sun, 24 Aug 2025 20:59:49 +0800 Subject: [PATCH 17/21] publish: specify oss endpoint --- publish/publish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/publish/publish.php b/publish/publish.php index d4069d9..a21ef16 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -97,6 +97,7 @@ function createOssClient(string $key, string $secret, string $region): OssClient 'secret' => $secret, ], 'region' => $region, + 'endpoint' => sprintf('oss-%s.aliyuncs.com', $region), ]); } From 8e58efa5b6018d8afce5c30056e4a43b2ed72f7f Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sun, 24 Aug 2025 21:12:21 +0800 Subject: [PATCH 18/21] publish: represent the crc64 in string format --- publish/Crc64.php | 4 ++-- publish/publish.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/publish/Crc64.php b/publish/Crc64.php index c1f6cbd..00946ad 100644 --- a/publish/Crc64.php +++ b/publish/Crc64.php @@ -156,7 +156,7 @@ final class Crc64 0xD80C07CD << 32 | 0x676F8394, 0x9AFCE626 << 32 | 0xCE85B507, ]; - public static function make(string $value): int + public static function make(string $value): string { // Final XOR: 0xFFFFFFFFFFFFFFFF $finalXor = (1 << 64) - 1; @@ -177,7 +177,7 @@ public static function make(string $value): int $checksum = static::reflect64($checksum); - return $checksum ^ $finalXor; + return sprintf('%u', $checksum ^ $finalXor); } private static function reflect8(int $value): int diff --git a/publish/publish.php b/publish/publish.php index a21ef16..a60cbdf 100644 --- a/publish/publish.php +++ b/publish/publish.php @@ -140,7 +140,7 @@ function fileUpload(OssClient $client, string $bucket, string $object, string $f ]); } -function fileChecksum(string $filename): int +function fileChecksum(string $filename): string { $contents = file_get_contents($filename); From ede745d90e96a1b07af94ad65da97b8d8cd915b4 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Mon, 25 Aug 2025 09:54:00 +0800 Subject: [PATCH 19/21] tweak the workflow --- .github/workflows/build.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 534464f..99b6d7e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: run: make test-setup test-${{ matrix.variant }} - name: Login to GitHub Container Registry - if: github.ref == 'refs/heads/main' + if: startsWith(github.ref, 'refs/heads/v') uses: docker/login-action@v3 with: registry: ghcr.io @@ -84,5 +84,5 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push to GitHub Container Registry - if: github.ref == 'refs/heads/main' + if: startsWith(github.ref, 'refs/heads/v') run: make push-${{ matrix.variant }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee13b7d..68c422e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Release on: release: - types: [created] + types: [published] jobs: changes: From d50def69597aa8567ec704e4ba95d4041412f509 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Mon, 25 Aug 2025 10:53:03 +0800 Subject: [PATCH 20/21] fix tag refs --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99b6d7e..15a0a62 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: run: make test-setup test-${{ matrix.variant }} - name: Login to GitHub Container Registry - if: startsWith(github.ref, 'refs/heads/v') + if: startsWith(github.ref, 'refs/tags/v') uses: docker/login-action@v3 with: registry: ghcr.io @@ -84,5 +84,5 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push to GitHub Container Registry - if: startsWith(github.ref, 'refs/heads/v') + if: startsWith(github.ref, 'refs/tags/v') run: make push-${{ matrix.variant }} From ab3ebf4fa815c20a23984231069539499e9ad95a Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Mon, 25 Aug 2025 11:10:44 +0800 Subject: [PATCH 21/21] build: compare with the previous release when contains release tag --- .github/workflows/build.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15a0a62..2cb2e33 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,17 +7,39 @@ jobs: changes: name: Detect Changes runs-on: ubuntu-latest - permissions: - pull-requests: read outputs: variants: ${{ steps.filter.outputs.changes }} steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: ${{ startsWith(github.ref, 'refs/tags/v') && 0 || 1 }} + + - name: Retrieve the previous release version + if: startsWith(github.ref, 'refs/tags/v') + id: previous_release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Attempt to get the tag of the second-to-last release + PREVIOUS_TAG=$(gh release list --limit 2 --json tagName | jq -r '. | select(length > 1) | .[1].tagName') + + if [[ -z "$PREVIOUS_TAG" ]]; then + echo "No previous release found. Falling back to the first commit." + REF=$(git rev-list --max-parents=0 HEAD) + else + echo "Found previous release: $PREVIOUS_TAG" + REF=$PREVIOUS_TAG + fi + + echo "The reference point is: $REF" + echo "ref=$REF" >> $GITHUB_OUTPUT + - uses: dorny/paths-filter@v3 id: filter with: filters: .github/filters.yml + base: ${{ startsWith(github.ref, 'refs/tags/v') && steps.previous_release.outputs.ref || '' }} build: needs: changes