Skip to content

Monorepo Split

Monorepo Split #30

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[@]}"