-
Notifications
You must be signed in to change notification settings - Fork 0
175 lines (161 loc) · 6.36 KB
/
split.yml
File metadata and controls
175 lines (161 loc) · 6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
name: Split monorepo
# Manual trigger only for now. Once the framework is production-ready and
# the deferred test coverage + PHPStan baseline cleanup land, change the
# trigger to:
# on:
# push:
# branches: [master]
# tags: ['v*']
# and the workflow will run automatically on every push and tag.
#
# See issue #14 for the full plan.
on:
workflow_dispatch:
inputs:
package:
description: 'Single package to split (leave blank to split all 16)'
required: false
type: choice
default: ''
options:
- ''
- cache
- common
- configuration
- container
- cookie
- courier
- data
- filesystem
- happen
- http
- middleware
- sanitation
- security
- session
- structure
- validation
dry_run:
description: 'Compute splits but skip pushing to sub-repos'
required: false
type: boolean
default: false
env:
SPLITSH_VERSION: v1.0.1
# Opt into Node 24 ahead of the June 2026 default flip; silences the
# "Node.js 20 actions are deprecated" warning emitted by actions/checkout
# and other JS-based actions on the current runner image.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
jobs:
# GitHub Actions doesn't allow matrix.* in job-level if: conditions —
# the matrix is what defines the jobs. To support a "single package only"
# input, we compute the matrix dynamically in this setup job and the
# split job consumes it via fromJSON.
setup-matrix:
name: Compute matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.compute.outputs.matrix }}
steps:
- name: Build matrix JSON
id: compute
env:
PACKAGE: ${{ github.event.inputs.package }}
run: |
set -euo pipefail
full='[
{"name":"cache", "path":"src/Altair/Cache"},
{"name":"common", "path":"src/Altair/Common"},
{"name":"configuration", "path":"src/Altair/Configuration"},
{"name":"container", "path":"src/Altair/Container"},
{"name":"cookie", "path":"src/Altair/Cookie"},
{"name":"courier", "path":"src/Altair/Courier"},
{"name":"data", "path":"src/Altair/Data"},
{"name":"filesystem", "path":"src/Altair/Filesystem"},
{"name":"happen", "path":"src/Altair/Happen"},
{"name":"http", "path":"src/Altair/Http"},
{"name":"middleware", "path":"src/Altair/Middleware"},
{"name":"sanitation", "path":"src/Altair/Sanitation"},
{"name":"security", "path":"src/Altair/Security"},
{"name":"session", "path":"src/Altair/Session"},
{"name":"structure", "path":"src/Altair/Structure"},
{"name":"validation", "path":"src/Altair/Validation"}
]'
if [[ -z "${PACKAGE}" ]]; then
matrix=$(jq -c '.' <<< "$full")
else
matrix=$(jq -c --arg p "$PACKAGE" '[.[] | select(.name == $p)]' <<< "$full")
if [[ "$(jq 'length' <<< "$matrix")" -eq 0 ]]; then
echo "::error::Unknown package '${PACKAGE}'"
exit 1
fi
fi
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
echo "Selected packages:"
jq '.[].name' <<< "$matrix"
split:
name: Split ${{ matrix.package.name }}
needs: setup-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.setup-matrix.outputs.matrix) }}
steps:
- name: Checkout (full history)
uses: actions/checkout@v4
with:
fetch-depth: 0
# Don't write the default GITHUB_TOKEN into git's extraheader config —
# that bot token only has write access to univeros/framework, and its
# Authorization header would shadow the SPLIT_TOKEN we embed in the
# push URL, causing pushes to sub-repos to be rejected with 403.
persist-credentials: false
- name: Install splitsh/lite
run: |
set -euo pipefail
mkdir -p /tmp/splitsh && cd /tmp/splitsh
curl -sSL -o splitsh.tar.gz \
"https://github.com/splitsh/lite/releases/download/${SPLITSH_VERSION}/lite_linux_amd64.tar.gz"
tar xzf splitsh.tar.gz
sudo mv splitsh-lite /usr/local/bin/
splitsh-lite --version
- name: Compute split for ${{ matrix.package.path }}
id: split
run: |
set -euo pipefail
sha=$(splitsh-lite --prefix="${{ matrix.package.path }}")
if [[ -z "$sha" ]]; then
echo "::error::splitsh-lite produced an empty SHA for ${{ matrix.package.path }}"
exit 1
fi
echo "Split SHA for ${{ matrix.package.name }}: $sha"
echo "sha=$sha" >> "$GITHUB_OUTPUT"
- name: Push split to univeros/${{ matrix.package.name }}
if: github.event.inputs.dry_run != 'true'
env:
SPLIT_TOKEN: ${{ secrets.SPLIT_TOKEN }}
run: |
set -euo pipefail
if [[ -z "${SPLIT_TOKEN:-}" ]]; then
echo "::error::SPLIT_TOKEN secret is not configured on this repository"
exit 1
fi
remote="https://x-access-token:${SPLIT_TOKEN}@github.com/univeros/${{ matrix.package.name }}.git"
sha="${{ steps.split.outputs.sha }}"
# Belt-and-suspenders: explicitly clear any Authorization extraheader
# for github.com on this single command so the URL-embedded PAT is the
# only credential git presents. This survives even if some upstream
# step has persisted the runner's GITHUB_TOKEN into git config.
git_push() {
git -c http.https://github.com/.extraheader= push "$@"
}
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
# Tag push: propagate the tag at the split SHA
echo "Pushing tag $GITHUB_REF to univeros/${{ matrix.package.name }}"
git_push "$remote" "${sha}:${GITHUB_REF}"
else
# Branch push: force-update master on the sub-repo
echo "Pushing $sha to univeros/${{ matrix.package.name }} master"
git_push "$remote" "${sha}:refs/heads/master" --force
fi