Repository navigation
Monorepo Split #30
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: Monorepo Split | |
| on: | |
| push: | |
| branches: [main] | |
| tags: | |
| - 'v*' | |
| paths: | |
| - '.github/monorepo-split.json' | |
| - '.github/scripts/monorepo-split-plan.php' | |
| - '.github/workflows/monorepo-split-plan.yml' | |
| - 'src/SonsOfPHP/**/composer.json' | |
| - 'src/**' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - '.github/monorepo-split.json' | |
| - '.github/scripts/monorepo-split-plan.php' | |
| - '.github/workflows/monorepo-split-plan.yml' | |
| - 'src/SonsOfPHP/**/composer.json' | |
| - 'src/**' | |
| workflow_dispatch: | |
| inputs: | |
| base: | |
| description: 'Base git ref for changed-package replay' | |
| required: false | |
| head: | |
| description: 'Head git ref to check out and publish' | |
| required: true | |
| default: 'main' | |
| tag: | |
| description: 'Optional release tag to publish instead of a branch range' | |
| required: false | |
| publish: | |
| description: 'Actually push split refs instead of calculating only' | |
| required: true | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| plan: | |
| name: Split packages | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| coverage: none | |
| - uses: actions/setup-go@v7 | |
| with: | |
| go-version: '1.22' | |
| cache: false | |
| - name: Install splitsh-lite | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential cmake libssh2-1-dev libssl-dev pkg-config zlib1g-dev | |
| curl -LsSf https://github.com/libgit2/libgit2/archive/refs/tags/v1.5.0.tar.gz | tar -xz | |
| cmake -S libgit2-1.5.0 -B libgit2-1.5.0/build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_INSTALL_PREFIX=/usr/local/libgit2-1.5 \ | |
| -DBUILD_TESTS=OFF | |
| cmake --build libgit2-1.5.0/build --parallel 2 | |
| sudo cmake --install libgit2-1.5.0/build | |
| echo "PKG_CONFIG_PATH=/usr/local/libgit2-1.5/lib/pkgconfig" >> "$GITHUB_ENV" | |
| echo "LD_LIBRARY_PATH=/usr/local/libgit2-1.5/lib" >> "$GITHUB_ENV" | |
| export PKG_CONFIG_PATH=/usr/local/libgit2-1.5/lib/pkgconfig | |
| export LD_LIBRARY_PATH=/usr/local/libgit2-1.5/lib | |
| GOBIN="$RUNNER_TEMP/bin" go install github.com/splitsh/lite@master | |
| sudo mv "$RUNNER_TEMP/bin/lite" /usr/local/bin/splitsh-lite | |
| splitsh-lite --help | |
| - uses: actions/create-github-app-token@v3 | |
| id: app-token | |
| if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish) | |
| with: | |
| client-id: ${{ secrets.MONOREPO_SPLIT_APP_CLIENT_ID }} | |
| private-key: ${{ secrets.MONOREPO_SPLIT_APP_PRIVATE_KEY }} | |
| owner: ${{ github.repository_owner }} | |
| permission-contents: write | |
| - name: Configure read-only repo token auth | |
| if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish) | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| echo "GIT_TERMINAL_PROMPT=0" >> "$GITHUB_ENV" | |
| auth_header="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GH_TOKEN" | base64 -w0)" | |
| git config --global http.https://github.com/.extraheader "$auth_header" | |
| - name: Validate split config | |
| run: php .github/scripts/monorepo-split-plan.php | |
| - name: Plan pull request package splits | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| php .github/scripts/monorepo-split-plan.php \ | |
| --base='${{ github.event.pull_request.base.sha }}' \ | |
| --head='${{ github.event.pull_request.head.sha }}' \ | |
| --origin=HEAD \ | |
| --calculate-splits | |
| - name: Publish mainline package splits | |
| if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') | |
| run: | | |
| php .github/scripts/monorepo-split-plan.php \ | |
| --base='${{ github.event.before }}' \ | |
| --head='${{ github.sha }}' \ | |
| --origin=HEAD \ | |
| --publish | |
| - name: Publish release tag package splits | |
| if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') | |
| run: | | |
| php .github/scripts/monorepo-split-plan.php \ | |
| --tag='${{ github.ref_name }}' \ | |
| --origin='${{ github.ref }}' \ | |
| --publish | |
| - name: Run manual split replay | |
| if: github.event_name == 'workflow_dispatch' | |
| env: | |
| BASE_REF: ${{ inputs.base }} | |
| HEAD_REF: ${{ inputs.head }} | |
| TAG_NAME: ${{ inputs.tag }} | |
| PUBLISH_SPLITS: ${{ inputs.publish }} | |
| run: | | |
| if [ -n "$TAG_NAME" ]; then | |
| git fetch --force origin "refs/tags/$TAG_NAME:refs/tags/$TAG_NAME" | |
| command=(php .github/scripts/monorepo-split-plan.php --tag="$TAG_NAME" --origin="refs/tags/$TAG_NAME") | |
| else | |
| if [ -z "$BASE_REF" ]; then | |
| echo "::error::Manual branch replay requires the base input." | |
| exit 1 | |
| fi | |
| git update-ref refs/heads/monorepo-split-replay-head "$HEAD_REF" | |
| command=(php .github/scripts/monorepo-split-plan.php --base="$BASE_REF" --head="$HEAD_REF" --origin=refs/heads/monorepo-split-replay-head) | |
| fi | |
| if [ "$PUBLISH_SPLITS" = "true" ]; then | |
| command+=(--publish) | |
| else | |
| command+=(--calculate-splits) | |
| fi | |
| "${command[@]}" |