Build #666
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 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| publish: | |
| description: 'Publish to repository' | |
| required: false | |
| default: false | |
| type: boolean | |
| package: | |
| description: 'Package to build' | |
| required: true | |
| default: 'adminer' | |
| add_noarch_builds: | |
| description: 'Include noarch packages' | |
| required: false | |
| default: true | |
| type: boolean | |
| add_noarch_dsm72_builds: | |
| description: 'Include noarch DSM 7.2 packages' | |
| required: false | |
| default: false | |
| type: boolean | |
| add_dsm72_builds: | |
| description: 'Include DSM 7.2 archs' | |
| required: false | |
| default: false | |
| type: boolean | |
| add_dsm71_builds: | |
| description: 'Include DSM 7.1 archs' | |
| required: false | |
| default: true | |
| type: boolean | |
| add_dsm62_builds: | |
| description: 'Include DSM 6.2 archs' | |
| required: false | |
| default: true | |
| type: boolean | |
| add_dsm52_builds: | |
| description: 'Include DSM 5.2 archs' | |
| required: false | |
| default: false | |
| type: boolean | |
| add_srm13_builds: | |
| description: 'Include SRM 1.3 archs' | |
| required: false | |
| default: false | |
| type: boolean | |
| add_srm12_builds: | |
| description: 'Include SRM 1.2 archs' | |
| required: false | |
| default: false | |
| type: boolean | |
| pull_request: | |
| paths: | |
| - 'spk/**' | |
| - 'cross/**' | |
| - 'python/**' | |
| - 'native/**' | |
| push: | |
| branches: | |
| - "**" | |
| paths: | |
| - 'spk/**' | |
| - 'cross/**' | |
| - 'python/**' | |
| - 'native/**' | |
| jobs: | |
| prepare: | |
| name: Prepare for Build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| arch_packages: ${{ steps.dependencies.outputs.arch_packages }} | |
| noarch_packages: ${{ steps.dependencies.outputs.noarch_packages }} | |
| has_min_dsm72_packages: ${{ steps.dependencies.outputs.has_min_dsm72_packages }} | |
| distrib_hash: ${{ steps.distrib-hash.outputs.hash }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Get changed spk_packages and dependency_folders for pull request | |
| if: github.event_name == 'pull_request' | |
| id: getchanges_pr | |
| run: | | |
| git diff --no-commit-id --name-only -r origin/master...${{github.event.pull_request.head.sha}} | grep -oP "^spk/\K[^\/]*" | sort -u | xargs | |
| echo "spk_packages=$(git diff --no-commit-id --name-only -r origin/master...${{github.event.pull_request.head.sha}} | grep -oP "^spk/\K[^\/]*" | sort -u | xargs)" >> $GITHUB_OUTPUT | |
| git diff --no-commit-id --name-only -r origin/master...${{github.event.pull_request.head.sha}} | grep -oP "(cross|python|native)/[^\/]*" | sort -u | xargs | |
| echo "dependency_folders=$(git diff --no-commit-id --name-only -r origin/master...${{github.event.pull_request.head.sha}} | grep -oP "(cross|python|native)/[^\/]*" | sort -u | xargs)" >> $GITHUB_OUTPUT | |
| - name: Get changed spk_packages and dependency_folders of last commit for push | |
| if: github.event_name == 'push' | |
| id: getchanges_push | |
| run: | | |
| git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep -oP "^spk/\K[^\/]*" | sort -u | xargs | |
| echo "spk_packages=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep -oP "^spk/\K[^\/]*" | sort -u | xargs)" >> $GITHUB_OUTPUT | |
| git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep -oP "(cross|python|native)/[^\/]*" | sort -u | xargs | |
| echo "dependency_folders=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep -oP "(cross|python|native)/[^\/]*" | sort -u | xargs)" >> $GITHUB_OUTPUT | |
| - name: Evaluate dependencies | |
| id: dependencies | |
| run: ./.github/actions/prepare.sh | |
| env: | |
| GH_SPK_PACKAGES: ${{ steps.getchanges_push.outputs.spk_packages }} ${{ steps.getchanges_pr.outputs.spk_packages }} | |
| GH_DEPENDENCY_FOLDERS: ${{ steps.getchanges_push.outputs.dependency_folders }} ${{ steps.getchanges_pr.outputs.dependency_folders }} | |
| USER_SPK_TO_BUILD: ${{ github.event.inputs.package }} | |
| - name: Restore distrib cache | |
| id: cache-restore | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: distrib | |
| # Use a placeholder key that will never match for the exact key, | |
| # forcing GitHub to use restore-keys to find the best available cache | |
| key: distrib-placeholder-${{ github.run_id }} | |
| restore-keys: | | |
| distrib- | |
| - name: Download source files | |
| run: ./.github/actions/download.sh | |
| env: | |
| DOWNLOAD_PACKAGES: ${{ steps.dependencies.outputs.download_packages }} | |
| ARCH_PACKAGES: ${{ steps.dependencies.outputs.arch_packages }} | |
| NOARCH_PACKAGES: ${{ steps.dependencies.outputs.noarch_packages }} | |
| - name: Compute distrib hash | |
| id: distrib-hash | |
| run: | | |
| # Compute a hash based on file paths and sizes (not content) for performance. | |
| # This is fast even with thousands of files since we don't read file contents. | |
| # Including file size ensures that if a corrupted file (.wrong) is replaced | |
| # by a fresh download with different size, the hash will change. | |
| # Format: "path size" per line, sorted for reproducibility, then hashed. | |
| if [ -d "distrib" ] && [ -n "$(ls -A distrib 2>/dev/null)" ]; then | |
| HASH=$(find distrib -type f -printf '%p %s\n' | sort | sha256sum | cut -d' ' -f1) | |
| else | |
| HASH="empty" | |
| fi | |
| echo "hash=$HASH" >> $GITHUB_OUTPUT | |
| echo "Distrib cache hash: $HASH" | |
| - name: Check if cache already exists | |
| id: cache-check | |
| run: | | |
| # Check if a cache with this exact hash already exists to avoid duplication. | |
| # We search for the exact key pattern to see if this content was already cached. | |
| CACHE_KEY="distrib-${{ steps.distrib-hash.outputs.hash }}" | |
| if gh cache list --json key | jq -e --arg key "$CACHE_KEY" '.[] | select(.key == $key)' > /dev/null 2>&1; then | |
| echo "Cache with key $CACHE_KEY already exists, skipping save" | |
| echo "save_cache=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "New cache content detected, will save with key: $CACHE_KEY" | |
| echo "save_cache=true" >> $GITHUB_OUTPUT | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Save distrib cache | |
| if: steps.cache-check.outputs.save_cache == 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: distrib | |
| key: distrib-${{ steps.distrib-hash.outputs.hash }} | |
| set-defaults: | |
| name: Set Defaults | |
| runs-on: ubuntu-latest | |
| needs: prepare | |
| outputs: | |
| matrix: ${{ steps.defaults.outputs.matrix }} | |
| has_entries: ${{ steps.defaults.outputs.has_entries }} | |
| steps: | |
| - id: defaults | |
| run: | | |
| # Retrieve inputs and package availability | |
| add_noarch_builds=${{ github.event.inputs.add_noarch_builds || 'false' }} | |
| add_noarch_dsm72_builds=${{ github.event.inputs.add_noarch_dsm72_builds || 'false' }} | |
| add_dsm72_builds=${{ github.event.inputs.add_dsm72_builds || 'false' }} | |
| add_dsm71_builds=${{ github.event.inputs.add_dsm71_builds || 'false' }} | |
| add_dsm62_builds=${{ github.event.inputs.add_dsm62_builds || 'false' }} | |
| add_dsm52_builds=${{ github.event.inputs.add_dsm52_builds || 'false' }} | |
| add_srm13_builds=${{ github.event.inputs.add_srm13_builds || 'false' }} | |
| add_srm12_builds=${{ github.event.inputs.add_srm12_builds || 'false' }} | |
| has_noarch_packages=$([ -n "${{ needs.prepare.outputs.noarch_packages }}" ] && echo "true" || echo "false") | |
| has_arch_packages=$([ -n "${{ needs.prepare.outputs.arch_packages }}" ] && echo "true" || echo "false") | |
| has_min_dsm72_packages=${{ needs.prepare.outputs.has_min_dsm72_packages || 'false' }} | |
| # Dynamic logic for automatic builds | |
| if [ "${{ github.event_name }}" != "workflow_dispatch" ]; then | |
| # Enable noarch builds if noarch packages exist | |
| add_noarch_builds=$([ "$has_noarch_packages" == "true" ] && echo "true" || echo "false") | |
| # Enable noarch DSM 7.2 builds if noarch packages exist and minimum DSM 7.2 requirements are met | |
| add_noarch_dsm72_builds=$([ "$has_noarch_packages" == "true" ] && [ "$has_min_dsm72_packages" == "true" ] && echo "true" || echo "false") | |
| # Enable DSM 7.2 builds if arch packages exist and minimum DSM 7.2 requirements are met | |
| add_dsm72_builds=$([ "$has_arch_packages" == "true" ] && [ "$has_min_dsm72_packages" == "true" ] && echo "true" || echo "false") | |
| # Enable DSM 7.1 builds if arch packages exist | |
| add_dsm71_builds=$([ "$has_arch_packages" == "true" ] && echo "true" || echo "false") | |
| # Enable DSM 6.2 builds if arch packages exist | |
| add_dsm62_builds=$([ "$has_arch_packages" == "true" ] && echo "true" || echo "false") | |
| fi | |
| # Build matrix | |
| matrix=$(jq -n '{"include": []}') | |
| # Helper function to add entries to the matrix | |
| add_to_matrix() { | |
| matrix=$(echo "$matrix" | jq --arg arch "$1" '.include += [{"arch": $arch}]') | |
| } | |
| # Add noarch builds | |
| if [ "$add_noarch_builds" == "true" ] && [ "$has_noarch_packages" == "true" ]; then | |
| add_to_matrix "noarch-1.1" | |
| add_to_matrix "noarch-3.1" | |
| add_to_matrix "noarch-6.1" | |
| add_to_matrix "noarch-7.0" | |
| fi | |
| # Add noarch DSM 7.2 builds | |
| if [ "$add_noarch_dsm72_builds" == "true" ] && [ "$has_noarch_packages" == "true" ]; then | |
| add_to_matrix "noarch-7.2" | |
| fi | |
| # Add DSM 7.2 builds | |
| if [ "$add_dsm72_builds" == "true" ] && [ "$has_arch_packages" == "true" ]; then | |
| add_to_matrix "x64-7.2" | |
| add_to_matrix "aarch64-7.2" | |
| add_to_matrix "armv7-7.2" | |
| fi | |
| # Add DSM 7.1 builds | |
| if [ "$add_dsm71_builds" == "true" ] && [ "$has_arch_packages" == "true" ]; then | |
| add_to_matrix "x64-7.1" | |
| add_to_matrix "aarch64-7.1" | |
| add_to_matrix "evansport-7.1" | |
| add_to_matrix "armv7-7.1" | |
| add_to_matrix "comcerto2k-7.1" | |
| fi | |
| # Add DSM 6.2 builds | |
| if [ "$add_dsm62_builds" == "true" ] && [ "$has_arch_packages" == "true" ]; then | |
| add_to_matrix "x64-6.2.4" | |
| add_to_matrix "aarch64-6.2.4" | |
| add_to_matrix "evansport-6.2.4" | |
| add_to_matrix "armv7-6.2.4" | |
| add_to_matrix "hi3535-6.2.4" | |
| add_to_matrix "88f6281-6.2.4" | |
| add_to_matrix "qoriq-6.2.4" | |
| fi | |
| # Add DSM 5.2 builds | |
| if [ "$add_dsm52_builds" == "true" ] && [ "$has_arch_packages" == "true" ]; then | |
| add_to_matrix "x86-5.2" | |
| add_to_matrix "88f6281-5.2" | |
| add_to_matrix "ppc853x-5.2" | |
| fi | |
| # Add SRM 1.3 builds | |
| if [ "$add_srm13_builds" == "true" ]; then | |
| add_to_matrix "aarch64-1.3" | |
| add_to_matrix "armv7-1.3" | |
| fi | |
| # Add SRM 1.2 builds | |
| if [ "$add_srm12_builds" == "true" ]; then | |
| add_to_matrix "armv7-1.2" | |
| fi | |
| # Output the final matrix | |
| echo "matrix=$(echo $matrix | jq -c)" >> $GITHUB_OUTPUT | |
| # Output if the matrix has entries | |
| echo "has_entries=$(jq -e '.include | length > 0' <<< "$matrix" > /dev/null && echo true || echo false)" >> $GITHUB_OUTPUT | |
| build: | |
| name: Build | |
| needs: [prepare, set-defaults] | |
| runs-on: ubuntu-latest | |
| if: ${{ needs.set-defaults.outputs.has_entries == 'true' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.set-defaults.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Cache toolchains | |
| uses: actions/cache@v5 | |
| # Do not cache qoriq toolchain. It must be built every time to install custom rust toolchain | |
| if: ${{ contains(matrix.arch,'qoriq') == false }} | |
| with: | |
| path: toolchain/*/work | |
| key: toolchain-${{ matrix.arch }}-v3-${{ hashFiles(format('toolchain/syno-{0}/digests',matrix.arch)) }} | |
| - name: Restore distrib cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: distrib | |
| # Use a placeholder key that will never match for the exact key, | |
| # forcing GitHub to use restore-keys to find the best available cache | |
| key: distrib-placeholder-${{ github.run_id }} | |
| restore-keys: | | |
| distrib- | |
| - name: Build Package (based on changed files) | |
| # We don't want to stop the build on errors. | |
| # Errors are reported in "Build Status" | |
| continue-on-error: true | |
| uses: docker://ghcr.io/synocommunity/spksrc:latest | |
| with: | |
| entrypoint: ./.github/actions/build.sh | |
| env: | |
| ARCH_PACKAGES: ${{ needs.prepare.outputs.arch_packages }} | |
| NOARCH_PACKAGES: ${{ needs.prepare.outputs.noarch_packages }} | |
| PUBLISH: ${{ github.event.inputs.publish }} | |
| API_KEY: ${{ secrets.PUBLISH_API_KEY }} | |
| PACKAGE_TO_PUBLISH: ${{ github.event.inputs.package }} | |
| # https://github.com/SynoCommunity/spksrc/wiki/Compile-and-build-rules | |
| GH_ARCH: ${{ matrix.arch }} | |
| BUILD_ERROR_FILE: /github/workspace/build_errors.txt | |
| BUILD_ERROR_LOGFILE: /github/workspace/build_log_errors.txt | |
| BUILD_UNSUPPORTED_FILE: /github/workspace/build_unsupported.txt | |
| BUILD_SUCCESS_FILE: /github/workspace/build_success.txt | |
| - name: Build Status | |
| id: build_status | |
| # We need this status since we don't want to stop the build on errors. | |
| # Here we fail on build errors found in the build error file. | |
| uses: docker://ghcr.io/synocommunity/spksrc:latest | |
| with: | |
| entrypoint: ./.github/actions/build_status.sh | |
| env: | |
| BUILD_ERROR_FILE: /github/workspace/build_errors.txt | |
| BUILD_ERROR_LOGFILE: /github/workspace/build_log_errors.txt | |
| BUILD_UNSUPPORTED_FILE: /github/workspace/build_unsupported.txt | |
| BUILD_SUCCESS_FILE: /github/workspace/build_success.txt | |
| - name: Upload artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: Packages for ${{ matrix.arch }} | |
| path: packages/*.spk | |
| if-no-files-found: ignore |