Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
433bcad
versioned packages
henderkes Dec 15, 2025
fb0d283
readme
henderkes Dec 15, 2025
6d3f390
use common package stream in all streams
henderkes Dec 15, 2025
9c631d1
delete source dirs after building to save CI space
henderkes Dec 18, 2025
c57c693
versioned fully? WIP
henderkes Dec 18, 2025
90daf15
Merge branch 'master' into versioned
henderkes Dec 18, 2025
ea34048
add package info for alpine
henderkes Dec 18, 2025
5212a49
Merge remote-tracking branch 'origin/master' into versioned
henderkes Dec 18, 2025
d2510d8
apk packages are not working yet, something about origin metadata mis…
henderkes Dec 18, 2025
ea702d8
use sh
henderkes Dec 18, 2025
a4b0fdb
use nfpm for creation of apk packages (fpm creates invalid crap)
henderkes Dec 18, 2025
73bc0f6
Merge remote-tracking branch 'origin/master' into versioned
henderkes Dec 20, 2025
0ca68b6
rework more stuff for versioning (only pie, php or frankenphp harcode…
henderkes Dec 20, 2025
922426c
don't remove source and download dir after it's too late
henderkes Dec 20, 2025
64b8703
rename variable for clarity
henderkes Dec 20, 2025
abeff8f
all command has to pass param
henderkes Dec 20, 2025
d12cd60
versioned seems working!
henderkes Dec 20, 2025
306e231
versioned packages do not conflict with other versions
henderkes Dec 21, 2025
838fe1d
pie wrapper cleanup (depend on sed on alpine)
henderkes Dec 21, 2025
bb31657
why is apk so shit
henderkes Dec 21, 2025
3a8c1c8
dont require sed
henderkes Dec 21, 2025
5a7db97
or do?
henderkes Dec 21, 2025
281293c
dont create debuginfo by default on alpine/deb
henderkes Dec 21, 2025
1156a78
some more versioning detection stuff
henderkes Dec 22, 2025
f6f8ed0
bring back debuginfo creation on rpm
henderkes Dec 22, 2025
418194a
add forgejo-helper, debian workflow on versioned branch
henderkes Dec 22, 2025
9f16fe8
Merge branch 'master' into versioned
henderkes Dec 22, 2025
c2596a6
fix workflow!
henderkes Dec 22, 2025
b6d0856
fuck
henderkes Dec 22, 2025
370473f
why is tmate not working?
henderkes Dec 22, 2025
512a183
fix tmate
henderkes Dec 22, 2025
588cb0e
params for the job to run selectively
henderkes Dec 22, 2025
71f9e8c
add php version to debian frankenphp package
henderkes Dec 23, 2025
af6b416
add apk workflow
henderkes Dec 23, 2025
15cd0ce
use debs instead of goreleaser
henderkes Dec 23, 2025
9787431
we don't need fpm for apks
henderkes Dec 23, 2025
32ec78a
+phpversion for debian packages that can have conflicting versions
henderkes Dec 23, 2025
ccda5a8
fml
henderkes Dec 23, 2025
a575f30
need to _85 for apks too
henderkes Dec 23, 2025
6b1431d
no more different email addresses, unify under pkg@
henderkes Dec 23, 2025
f36f97f
blub
henderkes Dec 23, 2025
61a08d0
Merge branch 'master' into versioned
henderkes Dec 23, 2025
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
17 changes: 11 additions & 6 deletions .github/workflows/build-apk-forgejo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,19 @@ jobs:
- name: Install APT dependencies
run: |
sudo apt-get update
sudo apt-get install -y curl ruby build-essential tar zstd python3 python3-requests
sudo apt-get install -y curl build-essential tar zstd python3 python3-requests
sudo apt-get upgrade -y
sudo gem install fpm

- name: Install nfpm
run: |
curl -sfL https://goreleaser.com/static/run | bash -s -- --version
curl -sfL https://goreleaser.com/static/run | bash -s -- install github.com/goreleaser/nfpm/v2/cmd/nfpm@latest
if [[ "${{ matrix.arch }}" == "aarch64" ]]; then
NFPM_ARCH="arm64"
else
NFPM_ARCH="amd64"
fi
curl -L -o nfpm.deb https://github.com/goreleaser/nfpm/releases/download/v2.44.0/nfpm_2.44.0_${NFPM_ARCH}.deb
sudo dpkg -i nfpm.deb
rm nfpm.deb

- name: Install composer
run: |
Expand Down Expand Up @@ -150,9 +155,9 @@ jobs:
PACKAGES_FLAG="--packages=${{ env.PACKAGES }}"
fi
if [[ -n "${ITERATION}" ]]; then
php bin/spp all --target=native-native-musl --phpv=${{ matrix.php-version }} --prefix="-zts" --type=apk --iteration="${ITERATION}" $PACKAGES_FLAG -dynamic
php bin/spp all --target="native-native-musl -dynamic" --phpv=${{ matrix.php-version }} --prefix="-zts" --type=apk --iteration="${ITERATION}" $PACKAGES_FLAG
else
php bin/spp all --target=native-native-musl --phpv=${{ matrix.php-version }} --prefix="-zts" --type=apk $PACKAGES_FLAG -dynamic
php bin/spp all --target="native-native-musl -dynamic" --phpv=${{ matrix.php-version }} --prefix="-zts" --type=apk $PACKAGES_FLAG
fi

- name: Upload to Forgejo
Expand Down
103 changes: 90 additions & 13 deletions .github/workflows/build-deb-forgejo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ name: Build and upload Debian packages to Forgejo
on:
workflow_dispatch:
inputs:
iteration:
description: "Optional: override package iteration (integer). Leave empty for auto"
required: false
default: ""
php_versions:
description: "Optional: PHP versions (comma-separated, e.g., 8.2,8.5). Leave empty for all"
required: false
default: ""
architectures:
description: "Optional: Architectures (comma-separated, e.g., amd64,arm64). Leave empty for all"
required: false
default: ""
debug_tmate:
description: "Open tmate session on failure"
type: boolean
Expand All @@ -15,9 +27,48 @@ permissions:
contents: read

jobs:
setup-matrix:
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Set up matrix
id: set-matrix
run: |
# Default values
default_php='["8.2","8.3","8.4","8.5"]'
default_arch='["amd64","arm64"]'

# Parse inputs or use defaults
if [[ -n "${INPUTS_PHP_VERSIONS}" ]]; then
php_versions=$(echo "${INPUTS_PHP_VERSIONS}" | jq -R 'split(",") | map(gsub("^\\s+|\\s+$";""))')
else
php_versions=$default_php
fi

if [[ -n "${INPUTS_ARCHITECTURES}" ]]; then
arch_versions=$(echo "${INPUTS_ARCHITECTURES}" | jq -R 'split(",") | map(gsub("^\\s+|\\s+$";""))')
else
arch_versions=$default_arch
fi

# Create matrix JSON (compact, single line)
matrix=$(jq -nc \
--argjson php "$php_versions" \
--argjson arch "$arch_versions" \
'{"php-version":$php,"arch":$arch}')

echo "matrix=$matrix" >> $GITHUB_OUTPUT
env:
INPUTS_PHP_VERSIONS: ${{ inputs.php_versions }}
INPUTS_ARCHITECTURES: ${{ inputs.architectures }}

build:
name: Build Debian packages for PHP ${{ matrix.php_version }} on ${{ matrix.arch }}
runs-on: ${{ matrix.arch == 'aarch64' && 'ubuntu-24.04-arm64' || 'ubuntu-24.04' }}
needs: setup-matrix
name: Build for ${{ matrix.arch }} PHP ${{ matrix.php-version }}
runs-on: ubuntu-24.04${{ matrix.arch == 'arm64' && '-arm' || '' }}
container:
image: debian:11
permissions:
Expand All @@ -26,13 +77,12 @@ jobs:
run:
shell: bash
strategy:
matrix:
php_version: ['8.2', '8.3', '8.4', '8.5']
arch: ['x86_64', 'aarch64']
fail-fast: false
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASH_ENV: /tmp/gha-bashenv
PHP_VERSION: ${{ matrix.php_version }}
ITERATION: ${{ inputs.iteration || '' }}

steps:
- name: Checkout code
Expand All @@ -41,10 +91,18 @@ jobs:
ref: versioned
persist-credentials: false

- name: Set architecture variables
run: |
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
echo "RPM_ARCH=aarch64" >> $GITHUB_ENV
else
echo "RPM_ARCH=x86_64" >> $GITHUB_ENV
fi

- name: Set PHP version short
run: |
# Convert "8.5" to "85"
PHP_VERSION_SHORT=$(echo "$PHP_VERSION" | tr -d '.')
PHP_VERSION_SHORT=$(echo "${{ matrix.php-version }}" | tr -d '.')
echo "PHP_VERSION_SHORT=$PHP_VERSION_SHORT" >> $GITHUB_ENV

- name: Bootstrap container
Expand All @@ -56,13 +114,13 @@ jobs:

- name: Install cmake
run: |
curl -o cmake.tar.gz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-${{ matrix.arch }}.tar.gz && \
curl -o cmake.tar.gz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$(uname -m).tar.gz && \
sudo tar -xzf cmake.tar.gz -C /usr/local --strip-components=1 && \
rm cmake.tar.gz

- name: Install composer
run: |
sudo curl -L https://files.henderkes.com/${{ matrix.arch }}-linux/php -o /usr/local/bin/php
sudo curl -L https://files.henderkes.com/${RPM_ARCH}-linux/php -o /usr/local/bin/php
sudo chmod +x /usr/local/bin/php
sudo curl -sS https://raw.githubusercontent.com/composer/getcomposer.org/f3108f64b4e1c1ce6eb462b159956461592b3e3e/web/installer | php -- --quiet
sudo mv composer.phar /usr/local/bin/composer
Expand Down Expand Up @@ -96,21 +154,40 @@ jobs:
rm downloads.tar.gz

- name: Build PHP packages
run: bin/spp all --target=${{ matrix.arch }}-native-gnu --phpv=${{ matrix.php_version }} --prefix="-zts" --type=deb
run: |
if [[ -n "${ITERATION}" ]]; then
bin/spp all --target=native-native-gnu --phpv=${{ matrix.php-version }} --prefix="-zts" --type=deb --iteration="${ITERATION}"
else
bin/spp all --target=native-native-gnu --phpv=${{ matrix.php-version }} --prefix="-zts" --type=deb
fi

- name: Upload to Forgejo
working-directory: dist/deb
run: |
../../bin/forgejo-helper upload deb "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.deb"
../../bin/forgejo-helper upload debian "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.deb"

- name: Upload logs on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: build-logs-deb-${{ matrix.arch }}-php${{ matrix.php_version }}
name: build-logs-${{ matrix.arch }}-php${{ matrix.php-version }}
path: vendor/crazywhalecc/static-php-cli/log

- name: Install tmate
if: ${{ failure() && inputs.debug_tmate == true }}
run: |
case "${RPM_ARCH}" in
x86_64) arch="amd64" ;;
aarch64) arch="arm64v8" ;;
esac
dir="tmate-2.4.0-static-linux-$arch"
curl -L "https://github.com/tmate-io/tmate/releases/download/2.4.0/$dir.tar.xz" | tar -xJ -O "$dir/tmate" > /usr/bin/tmate
chmod +x /usr/bin/tmate

- name: Setup tmate session
if: ${{ failure() && inputs.debug_tmate == true }}
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3
timeout-minutes: 10
with:
install-dependencies: false
sudo: false
timeout-minutes: 30
9 changes: 1 addition & 8 deletions .github/workflows/build-gcc-deb-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,7 @@ jobs:
rm downloads.tar.gz

- name: Build PHP
run: php bin/spp build --target=native-native-gnu --phpv=${{ matrix.php-version }}

- name: Remove spc build dir to clear up space for gh runners
run: sudo rm -rf vendor/crazywhalecc/static-php-cli/source vendor/crazywhalecc/static-php-cli/buildroot

- name: Build deb packages
run: php bin/spp package --target=native-native-gnu --type=deb --phpv=${{ matrix.php-version }}
run: php bin/spp all --target=native-native-gnu --phpv=${{ matrix.php-version }} --prefix="-zts" --type=deb

- name: Stage deb artifacts
run: |
Expand Down Expand Up @@ -226,4 +220,3 @@ jobs:
# if: ${{ failure() && github.event_name == 'workflow_dispatch' }}
# uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3
# timeout-minutes: 10
# token:
25 changes: 20 additions & 5 deletions .github/workflows/spc-download.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Set up PHP
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: '8.4'
tools: composer:v2
- name: Set architecture variables
run: |
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
echo "RPM_ARCH=aarch64" >> $GITHUB_ENV
else
echo "RPM_ARCH=x86_64" >> $GITHUB_ENV
fi

- name: Install composer
run: |
sudo curl -L https://files.henderkes.com/${RPM_ARCH}-linux/php -o /usr/local/bin/php
sudo chmod +x /usr/local/bin/php
sudo curl -sS https://raw.githubusercontent.com/composer/getcomposer.org/f3108f64b4e1c1ce6eb462b159956461592b3e3e/web/installer | php -- --quiet
sudo mv composer.phar /usr/local/bin/composer

- name: Checkout code
uses: actions/checkout@v4
Expand Down Expand Up @@ -58,3 +67,9 @@ jobs:
run: gh workflow run build-gcc-deb-packages.yml
env:
GH_TOKEN: ${{ secrets.GH_PAT }} # use our own user as the triggering user

- name: Trigger build-deb-forgejo workflow on versioned branch
if: success()
run: gh workflow run build-deb-forgejo.yml --ref versioned
env:
GH_TOKEN: ${{ secrets.GH_PAT }} # use our own user as the triggering user
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ A tool for building and packaging PHP and shared extensions with static-php-cli.

1. Clone the repository:
```
git clone https://github.com/static-php/spc-packages.git
git clone https://github.com/static-php/packages.git
cd spc-packages
```

Expand Down
41 changes: 34 additions & 7 deletions bin/createrepo_static
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def parse_rpm_info(filename):
basename = os.path.basename(filename)

# Match standard php-zts RPMs
match_php = re.match(r'(?P<name>php-zts-[^-]+)-(?P<version>\d+\.\d+\.\d+)-(?P<release>[^.]+)\.(?P<arch>[^.]+)\.rpm', basename)
# Format: php-zts-cli-8.5.1-1.el10.x86_64.rpm (with optional .el10/.el9/etc)
match_php = re.match(r'(?P<name>php-zts-[^-]+)-(?P<version>\d+\.\d+\.\d+)-(?P<release>[^.]+)(?:\.[^.]+)?\.(?P<arch>x86_64|aarch64|noarch)\.rpm', basename)
if match_php:
name = match_php.group("name")
version = match_php.group("version")
Expand All @@ -30,7 +31,8 @@ def parse_rpm_info(filename):
return name, version, release, arch, stream

# Match extension packages
match_ext = re.match(r'(?P<name>php-zts-[^-]+)-(?P<version>\d+\.\d+\.\d+_\d+)-(?P<release>[^.]+)\.(?P<arch>[^.]+)\.rpm', basename)
# Format: php-zts-apcu-5.1.28_85-1.el10.x86_64.rpm (with optional .el10/.el9/etc)
match_ext = re.match(r'(?P<name>php-zts-[^-]+)-(?P<version>\d+\.\d+\.\d+(?:~[a-z0-9]+)?_\d+)-(?P<release>[^.]+)(?:\.[^.]+)?\.(?P<arch>x86_64|aarch64|noarch)\.rpm', basename)
if match_ext:
name = match_ext.group("name")
version = match_ext.group("version")
Expand All @@ -46,7 +48,8 @@ def parse_rpm_info(filename):
return name, version, release, arch, stream

# Match frankenphp
match_franken = re.match(r'(frankenphp)-(?P<version>\d+\.\d+\.\d+_\d+)-(?P<release>\d+)\.(?P<arch>[^.]+)\.rpm', basename)
# Format: frankenphp-1.11.0_85-1.el10.x86_64.rpm (with optional .el10/.el9/etc)
match_franken = re.match(r'(frankenphp)-(?P<version>\d+\.\d+\.\d+_\d+)-(?P<release>\d+)(?:\.[^.]+)?\.(?P<arch>x86_64|aarch64|noarch)\.rpm', basename)
if match_franken:
name = match_franken.group(1)
version = match_franken.group("version")
Expand All @@ -56,14 +59,36 @@ def parse_rpm_info(filename):
stream = f"8.{php_patch[-1]}"
return name, version, release, arch, stream

# Match static-php
match_static = re.match(r'(static-php)-(?P<version>\d+)-(?P<release>\d+)\.(?P<arch>[^.]+)\.rpm', basename)
if match_static:
name = match_static.group(1)
version = match_static.group("version")
release = match_static.group("release")
arch = match_static.group("arch")
stream = "common"
return name, version, release, arch, stream

return None

def build_module_structure(rpm_map, platform):
documents = []
timestamp = int(datetime.now(timezone.utc).strftime('%Y%m%d'))

# Collect common artifacts (static-php)
common_artifacts = []
if "common" in rpm_map:
for pkg in rpm_map["common"]:
info = parse_rpm_info(pkg)
if info:
name, version, release, arch, _ = info
common_artifacts.append(f"{name}-0:{version}-{release}.{arch}")

for stream, pkg_list in sorted(rpm_map.items()):
artifacts = []
if stream == "common":
continue

artifacts = common_artifacts.copy()

for pkg in sorted(pkg_list):
info = parse_rpm_info(pkg)
Expand Down Expand Up @@ -128,10 +153,12 @@ for rpm in rpm_files:
# Build modules.yaml
modules_yaml = build_module_structure(rpm_map, platform)

# Determine highest stream for default
# Determine highest stream for default (exclude "common")
if rpm_map:
default_stream = sorted(rpm_map.keys())[-1] # Use highest PHP version
modules_yaml.append(build_defaults_document(default_stream))
streams = [s for s in rpm_map.keys() if s != "common"]
if streams:
default_stream = sorted(streams)[-1]
modules_yaml.append(build_defaults_document(default_stream))

output_path = os.path.join(os.getcwd(), "modules.yaml")
with open(output_path, "w") as f:
Expand Down
Loading