Build and upload Alpine APK packages to Forgejo #177
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and upload Alpine APK 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., x86_64,aarch64). Leave empty for all" | |
| required: false | |
| default: "" | |
| packages: | |
| description: "Optional: override packages list. Leave empty for default" | |
| required: false | |
| default: "" | |
| debug_tmate: | |
| description: "Open tmate session on failure" | |
| type: boolean | |
| required: false | |
| default: false | |
| repository_dispatch: | |
| types: [spc-download] | |
| permissions: | |
| contents: read | |
| packages: read | |
| jobs: | |
| setup-matrix: | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| outputs: | |
| libs-pairs: ${{ steps.set-matrix.outputs.libs-pairs }} | |
| php-versions: ${{ steps.set-matrix.outputs.php-versions }} | |
| steps: | |
| - name: Set up matrix | |
| id: set-matrix | |
| run: | | |
| default_php='["8.2","8.3","8.4","8.5"]' | |
| default_arch='["x86_64","aarch64"]' | |
| if [[ -n "${INPUTS_PHP_VERSIONS}" ]]; then | |
| php_versions=$(echo "${INPUTS_PHP_VERSIONS}" | jq -Rc 'split(",") | map(gsub("^\\s+|\\s+$";""))') | |
| else | |
| php_versions=$default_php | |
| fi | |
| if [[ -n "${INPUTS_ARCHITECTURES}" ]]; then | |
| arch_versions=$(echo "${INPUTS_ARCHITECTURES}" | jq -Rc 'split(",") | map(gsub("^\\s+|\\s+$";""))') | |
| else | |
| arch_versions=$default_arch | |
| fi | |
| libs_pairs=$(jq -nc --argjson arch "$arch_versions" '{include: [$arch[] as $r | {arch: $r}]}') | |
| echo "libs-pairs=$libs_pairs" >> $GITHUB_OUTPUT | |
| echo "php-versions=$php_versions" >> $GITHUB_OUTPUT | |
| env: | |
| INPUTS_PHP_VERSIONS: ${{ inputs.php_versions }} | |
| INPUTS_ARCHITECTURES: ${{ inputs.architectures }} | |
| build-libs: | |
| needs: setup-matrix | |
| name: Build libs (${{ matrix.arch }}) | |
| runs-on: ${{ matrix.arch == 'x86_64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} | |
| container: | |
| image: ghcr.io/static-php/packages-builder-alpine:latest | |
| permissions: | |
| contents: write | |
| packages: read | |
| defaults: | |
| run: | |
| shell: bash | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.setup-matrix.outputs.libs-pairs) }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Compute buildroot cache key | |
| id: cache-key | |
| run: | | |
| set -euo pipefail | |
| WEEK=$(date -u +%G-%V) | |
| echo "key=buildroot-apk-${{ matrix.arch }}-${WEEK}" >> $GITHUB_OUTPUT | |
| - name: Restore buildroot cache | |
| id: cache | |
| uses: ./.github/actions/buildroot-cache | |
| with: | |
| mode: restore | |
| key: ${{ steps.cache-key.outputs.key }} | |
| - name: Prepare cache directories | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: composer config -g cache-dir | |
| - name: Cache Composer downloads | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.cache/composer | |
| key: composer-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| composer- | |
| - name: Install vendor | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: composer install --no-interaction --prefer-dist --no-progress | |
| - name: Download artifact from spc-download.yml | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 | |
| with: | |
| workflow: spc-download.yml | |
| name: downloads-tarball | |
| branch: master | |
| search_artifacts: true | |
| - name: Extract with permissions | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| mkdir -p downloads | |
| tar -xzf downloads.tar.gz -C downloads | |
| rm downloads.tar.gz | |
| - name: Build libs | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: bin/spp build --target="native-native-musl -dynamic" --phpv=8.5 --type=apk --libs-only | |
| - name: Pack buildroot | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: tar --zstd -cf buildroot.tar.zst buildroot | |
| - name: Save buildroot cache | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: ./.github/actions/buildroot-cache | |
| with: | |
| mode: save | |
| key: ${{ steps.cache-key.outputs.key }} | |
| - name: Upload logs on failure | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: build-logs-libs-${{ matrix.arch }} | |
| path: log | |
| - name: Setup tmate session | |
| if: ${{ failure() && inputs.debug_tmate == true }} | |
| uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3 | |
| timeout-minutes: 30 | |
| compute-build-matrix: | |
| needs: [setup-matrix, build-libs] | |
| runs-on: ubuntu-24.04 | |
| if: ${{ !cancelled() }} | |
| permissions: | |
| actions: read | |
| outputs: | |
| matrix: ${{ steps.filter.outputs.matrix }} | |
| any: ${{ steps.filter.outputs.any }} | |
| steps: | |
| - name: Filter build matrix to arches with successful libs | |
| id: filter | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSIONS: ${{ needs.setup-matrix.outputs.php-versions }} | |
| run: | | |
| set -euo pipefail | |
| succeeded=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/jobs" --paginate \ | |
| --jq '.jobs[] | select(.conclusion == "success" and (.name | test("^Build libs \\("))) | .name' \ | |
| | sed -E 's/^Build libs \(([^)]+)\)$/\1/' \ | |
| | sort -u) | |
| echo "Successful libs arches:" | |
| printf '%s\n' "$succeeded" | |
| include=$(jq -nc --arg s "$succeeded" --argjson p "$PHP_VERSIONS" ' | |
| ($s | split("\n") | map(select(length > 0) | {arch: .})) as $arches | | |
| [ $arches[] as $a | $p[] as $php | $a + {"php-version": $php} ] | |
| ') | |
| count=$(jq 'length' <<< "$include") | |
| echo "Filtered combos: $count" | |
| printf '%s\n' "$include" | jq . | |
| if [[ "$count" -gt 0 ]]; then | |
| echo "any=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "any=false" >> $GITHUB_OUTPUT | |
| fi | |
| echo "matrix={\"include\":$include}" >> $GITHUB_OUTPUT | |
| build: | |
| needs: [compute-build-matrix] | |
| if: ${{ !cancelled() && needs.compute-build-matrix.outputs.any == 'true' }} | |
| name: Build for ${{ matrix.arch }} PHP ${{ matrix.php-version }} | |
| runs-on: ${{ matrix.arch == 'x86_64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} | |
| container: | |
| image: ghcr.io/static-php/packages-builder-alpine:latest | |
| permissions: | |
| contents: read | |
| packages: read | |
| defaults: | |
| run: | |
| shell: bash | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.compute-build-matrix.outputs.matrix) }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| ITERATION: ${{ inputs.iteration || '' }} | |
| PACKAGES: ${{ inputs.packages || '' }} | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Set PHP version short | |
| run: | | |
| # Convert "8.5" to "85" | |
| PHP_VERSION_SHORT=$(echo "${{ matrix.php-version }}" | tr -d '.') | |
| echo "PHP_VERSION_SHORT=$PHP_VERSION_SHORT" >> $GITHUB_ENV | |
| - name: Prepare cache directories | |
| run: composer config -g cache-dir | |
| - name: Cache Composer downloads | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.cache/composer | |
| key: composer-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| composer- | |
| - name: Install vendor | |
| run: composer install --no-interaction --prefer-dist --no-progress | |
| - name: Download artifact from spc-download.yml | |
| uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 | |
| with: | |
| workflow: spc-download.yml | |
| name: downloads-tarball | |
| branch: master | |
| search_artifacts: true | |
| - name: Extract with permissions | |
| run: | | |
| mkdir -p downloads | |
| tar -xzf downloads.tar.gz -C downloads | |
| rm downloads.tar.gz | |
| - name: Compute buildroot cache key | |
| id: cache-key | |
| run: | | |
| set -euo pipefail | |
| WEEK=$(date -u +%G-%V) | |
| echo "key=buildroot-apk-${{ matrix.arch }}-${WEEK}" >> $GITHUB_OUTPUT | |
| - name: Restore buildroot cache | |
| uses: ./.github/actions/buildroot-cache | |
| with: | |
| mode: restore | |
| key: ${{ steps.cache-key.outputs.key }} | |
| fail-on-cache-miss: true | |
| - name: Extract buildroot | |
| run: | | |
| tar --zstd -xf buildroot.tar.zst | |
| rm buildroot.tar.zst | |
| - name: Build PHP packages | |
| run: | | |
| PACKAGES_FLAG="" | |
| if [[ -n "${{ env.PACKAGES }}" ]]; then | |
| PACKAGES_FLAG="--packages=${{ env.PACKAGES }}" | |
| fi | |
| ITERATION_FLAG="" | |
| if [[ -n "${ITERATION}" ]]; then | |
| ITERATION_FLAG="--iteration=${ITERATION}" | |
| fi | |
| php bin/spp all --target="native-native-musl -dynamic" --phpv=${{ matrix.php-version }} --prefix="-zts" --type=apk $ITERATION_FLAG $PACKAGES_FLAG | |
| - name: Upload logs on failure | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: build-logs-${{ matrix.arch }}-php${{ matrix.php-version }} | |
| path: log | |
| - name: Upload to Forgejo Host 1 | |
| working-directory: dist/apk | |
| run: | | |
| echo "listing from host 1" | |
| ../../bin/forgejo-helper list alpine "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.apk" | |
| echo "uploading to host 1" | |
| ../../bin/forgejo-helper upload alpine "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.apk" | |
| - name: Upload to Forgejo Host 2 | |
| working-directory: dist/apk | |
| continue-on-error: true | |
| run: | | |
| echo "listing from host 2" | |
| ../../bin/forgejo-helper --host=2 list alpine "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.apk" | |
| echo "uploading to host 2" | |
| ../../bin/forgejo-helper --host=2 upload alpine "${{ env.PHP_VERSION_SHORT }}" "${{ secrets.FORGEJO_PASSWORD }}" "*.apk" | |
| - name: Setup tmate session | |
| if: ${{ failure() && inputs.debug_tmate == true }} | |
| uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3 | |
| timeout-minutes: 30 |