-
Notifications
You must be signed in to change notification settings - Fork 1
236 lines (211 loc) · 9.31 KB
/
Copy pathcross-repo-verify.yml
File metadata and controls
236 lines (211 loc) · 9.31 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
name: Cross-repo wire-format verify
# Runs on every PR (no path filter at trigger level — branch-protection rules can require
# these checks without GitHub leaving them pending on path-skipped PRs). The relevance
# check happens inside the job, and irrelevant PRs early-exit with success.
#
# Sister workflow: app-main's .github/workflows/cross-repo-verify.yml (A3) fires the same
# shape from its direction. Each producer's PRs trigger the matching consumer suites
# against this PR's HEAD via INTEROP_FIXTURE_OVERRIDES.
on:
pull_request:
branches: [ main ]
permissions:
contents: read
concurrency:
group: cross-repo-verify-${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
# Path prefixes that can affect the bytes octi-web puts on the wire AND that are
# actually exercised by the consumer fixtures in src/__interop__/published/. Entries
# ending in `/` match any file under that prefix; bare file entries must match exactly.
# Keep this allowlist tight — over-firing turns into "every PR pays the cross-repo CI
# cost for changes that can't actually break consumers".
ALLOWLIST: |
src/modules/
src/__interop__/published/
src/protocol/connector-id.ts
src/util/base64.ts
tools/generate-fixtures.ts
.github/workflows/cross-repo-verify.yml
jobs:
verify-octi:
name: Verify app-main decodes this PR's wire bytes
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Checkout this repo at PR head
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
path: octi-web
# Full history so `git merge-base` finds the PR's branch point on main.
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Detect wire-format-relevant changes
id: changed
working-directory: octi-web
shell: bash
run: |
set -euo pipefail
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
merge_base="$(git merge-base "$base" "$head")"
matches_allowlist() {
local path="$1" prefix
while IFS= read -r prefix; do
prefix="${prefix#"${prefix%%[![:space:]]*}"}"
[[ -z "$prefix" ]] && continue
if [[ "$prefix" == */ ]]; then
[[ "$path" == "$prefix"* ]] && return 0
else
[[ "$path" == "$prefix" ]] && return 0
fi
done <<< "$ALLOWLIST"
return 1
}
relevant=false
while IFS= read -r -d '' path; do
if matches_allowlist "$path"; then
echo "relevant: $path"
relevant=true
fi
done < <(git diff --name-only --no-renames -z "$merge_base" "$head" --)
echo "relevant=$relevant" >> "$GITHUB_OUTPUT"
if [[ "$relevant" == "false" ]]; then
echo "no wire-format-relevant paths changed; consumer verify will be skipped."
fi
- name: Checkout app-main
if: steps.changed.outputs.relevant == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: d4rken-org/octi
persist-credentials: false
path: app-main
- name: Setup JDK 21
if: steps.changed.outputs.relevant == 'true'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Gradle wrapper
if: steps.changed.outputs.relevant == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.gradle/wrapper
!~/.gradle/wrapper/dists/**/gradle*.zip
# Cache keys are namespaced per consumer repo so the two jobs don't restore each
# other's incompatible caches across runs.
key: ${{ runner.os }}-app-main-gradle-wrapper-${{ hashFiles('app-main/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-app-main-gradle-wrapper-
- name: Cache Gradle dependencies
if: steps.changed.outputs.relevant == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.gradle/caches
key: ${{ runner.os }}-app-main-gradle-caches-${{ hashFiles('app-main/**/*.gradle*', 'app-main/**/gradle-wrapper.properties', 'app-main/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-app-main-gradle-caches-
- name: Run app-main module tests with fixture override
if: steps.changed.outputs.relevant == 'true'
working-directory: app-main
env:
# Override app-main's pin of d4rken-org/octi-web with this PR's HEAD SHA. The
# multi-source resolver drops the committed manifest_sha256 trust anchor for this
# source; per-file sha256s in the freshly-fetched manifest stay as the anchor.
INTEROP_FIXTURE_OVERRIDES: '{"d4rken-org/octi-web":"${{ github.event.pull_request.head.sha }}"}'
run: |
echo "Running app-main module tests against this PR's octi-web HEAD (${{ github.event.pull_request.head.sha }})"
chmod +x ./gradlew
# Only the modules that consume octi-web's fixtures need to run — the full :test
# graph would build app + UI variants that don't exercise this contract and would
# waste ~10 minutes per PR.
./gradlew :modules-meta:testDebugUnitTest :modules-clipboard:testDebugUnitTest :modules-files:testDebugUnitTest
verify-desktop:
name: Verify octi-desktop decodes this PR's wire bytes
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Checkout this repo at PR head
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
path: octi-web
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Detect wire-format-relevant changes
id: changed
working-directory: octi-web
shell: bash
run: |
set -euo pipefail
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
merge_base="$(git merge-base "$base" "$head")"
matches_allowlist() {
local path="$1" prefix
while IFS= read -r prefix; do
prefix="${prefix#"${prefix%%[![:space:]]*}"}"
[[ -z "$prefix" ]] && continue
if [[ "$prefix" == */ ]]; then
[[ "$path" == "$prefix"* ]] && return 0
else
[[ "$path" == "$prefix" ]] && return 0
fi
done <<< "$ALLOWLIST"
return 1
}
relevant=false
while IFS= read -r -d '' path; do
if matches_allowlist "$path"; then
echo "relevant: $path"
relevant=true
fi
done < <(git diff --name-only --no-renames -z "$merge_base" "$head" --)
echo "relevant=$relevant" >> "$GITHUB_OUTPUT"
if [[ "$relevant" == "false" ]]; then
echo "no wire-format-relevant paths changed; consumer verify will be skipped."
fi
- name: Checkout octi-desktop
if: steps.changed.outputs.relevant == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: d4rken-org/octi-desktop
persist-credentials: false
path: octi-desktop
- name: Setup JDK 21
if: steps.changed.outputs.relevant == 'true'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Gradle wrapper
if: steps.changed.outputs.relevant == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.gradle/wrapper
!~/.gradle/wrapper/dists/**/gradle*.zip
key: ${{ runner.os }}-octi-desktop-gradle-wrapper-${{ hashFiles('octi-desktop/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-octi-desktop-gradle-wrapper-
- name: Cache Gradle dependencies
if: steps.changed.outputs.relevant == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.gradle/caches
key: ${{ runner.os }}-octi-desktop-gradle-caches-${{ hashFiles('octi-desktop/**/*.gradle*', 'octi-desktop/**/gradle-wrapper.properties', 'octi-desktop/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-octi-desktop-gradle-caches-
- name: Run octi-desktop tests with fixture override
if: steps.changed.outputs.relevant == 'true'
working-directory: octi-desktop
env:
INTEROP_FIXTURE_OVERRIDES: '{"d4rken-org/octi-web":"${{ github.event.pull_request.head.sha }}"}'
run: |
echo "Running octi-desktop tests against this PR's octi-web HEAD (${{ github.event.pull_request.head.sha }})"
chmod +x ./gradlew
./gradlew test