-
Notifications
You must be signed in to change notification settings - Fork 1.3k
255 lines (227 loc) · 9.97 KB
/
Copy pathci.yml
File metadata and controls
255 lines (227 loc) · 9.97 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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
static-checks:
name: Static checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22"
- name: Check shell syntax
shell: bash
run: |
while IFS= read -r file; do
bash -n "$file"
done < <(
find macos -type f \( -name '*.sh' -o -name '*.command' \) \
! -path '*/release/*' -print
)
- name: Check Node.js syntax
shell: bash
run: |
while IFS= read -r file; do
node --check "$file" >/dev/null
done < <(
find runtime tools macos windows -type f \( -name '*.mjs' -o -name '*.js' \) -print
)
- name: Check Windows PowerShell source encoding
shell: bash
run: |
node <<'NODE'
const fs = require("node:fs");
const path = require("node:path");
function visit(directory) {
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
const file = path.join(directory, entry.name);
if (entry.isDirectory()) visit(file);
if (!entry.isFile() || path.extname(file) !== ".ps1") continue;
const bytes = fs.readFileSync(file);
const hasBom = bytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf]));
const content = hasBom ? bytes.subarray(3) : bytes;
if (content.some((byte) => byte >= 0x80) && !hasBom) {
throw new Error(`${file}: non-ASCII PowerShell 5.1 source requires a UTF-8 BOM`);
}
}
}
visit("windows");
NODE
- name: Check runtime safety assertions
shell: bash
run: |
if grep -R -n -E 'dream-skin-skin|DREAM_SKIN_SKIN|1\.0\.0-rc2' \
macos/scripts macos/assets >/dev/null; then
printf 'Legacy release-candidate identifiers remain in runtime files.\n' >&2
exit 1
fi
if grep -R -n -E '(writeFile|rename|copyFile|rm).*app\.asar' \
macos/scripts >/dev/null; then
printf 'A runtime script appears to mutate app.asar.\n' >&2
exit 1
fi
if grep -R -n --include='*.ps1' --include='*.iss' \
-F -- '-ExecutionPolicy Bypass' windows/scripts windows/installer >/dev/null; then
printf 'Windows runtime or installer code bypasses the PowerShell execution policy.\n' >&2
exit 1
fi
if grep -n -E '/usr/bin/python3|(^|[[:space:]])eval([[:space:]]|$)' \
macos/scripts/common-macos.sh >/dev/null; then
printf 'The macOS runtime must parse state without python3 or eval.\n' >&2
exit 1
fi
if grep -n -E 'target\.(title|url)' \
macos/scripts/injector.mjs windows/scripts/injector.mjs >/dev/null; then
printf 'Injector logs and results must not record page titles or URLs; keep only target IDs and structural markers.\n' >&2
exit 1
fi
if grep -n -E '(document\.title|location\.href)' \
macos/scripts/injector.mjs windows/scripts/injector.mjs >/dev/null; then
printf 'Injector renderer probes must not read the page title or URL back to the host.\n' >&2
exit 1
fi
for injector in macos/scripts/injector.mjs windows/scripts/injector.mjs; do
if grep -n -E '\.replace\("__DREAM_SKIN_[A-Z0-9_]+_JSON__", [^(]' \
"$injector" >/dev/null; then
printf '%s: payload placeholders must use function replacements so a theme name containing $ cannot corrupt the payload.\n' \
"$injector" >&2
exit 1
fi
done
- name: Check version consistency
shell: bash
run: |
expected="$(tr -d '\r\n' < macos/VERSION)"
windows_version="$(tr -d '\r\n' < windows/VERSION)"
linux_version="$(tr -d '\r\n' < linux/VERSION)"
package_version="$(node -p "JSON.parse(require('fs').readFileSync('macos/package.json','utf8')).version")"
common="$(sed -n 's/^SKIN_VERSION="\([^"]*\)"$/\1/p' macos/scripts/common-macos.sh)"
macos_injector="$(sed -n 's/^const SKIN_VERSION = "\([^"]*\)";$/\1/p' macos/scripts/injector.mjs)"
windows_injector="$(sed -n 's/^const SKIN_VERSION = "\([^"]*\)";$/\1/p' windows/scripts/injector.mjs)"
linux_common="$(sed -n 's/^SKIN_VERSION="\([^"]*\)"$/\1/p' linux/scripts/common-linux.sh)"
linux_injector="$(sed -n 's/^const SKIN_VERSION = "\([^"]*\)";$/\1/p' linux/scripts/injector.mjs)"
test -n "$expected"
test "$windows_version" = "$expected"
test "$linux_version" = "$expected"
test "$package_version" = "$expected"
test "$common" = "$expected"
test "$macos_injector" = "$expected"
test "$windows_injector" = "$expected"
test "$linux_common" = "$expected"
test "$linux_injector" = "$expected"
- name: Run portable Node.js regressions
shell: bash
run: |
node --test macos/tests/*.test.mjs
node --test windows/tests/*.test.mjs
node --test tools/*.test.mjs
node macos/scripts/injector.mjs --check-payload >/dev/null
node windows/scripts/injector.mjs --check-payload >/dev/null
windows-tests:
name: Windows (${{ matrix.name }})
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- name: Windows PowerShell 5.1
executable: powershell.exe
- name: PowerShell 7
executable: pwsh.exe
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22"
- name: Run Windows regression suite
shell: cmd
run: ${{ matrix.executable }} -NoLogo -NoProfile -ExecutionPolicy RemoteSigned -File .\windows\tests\run-tests.ps1
- name: Run Windows installer static checks
shell: cmd
run: ${{ matrix.executable }} -NoLogo -NoProfile -ExecutionPolicy RemoteSigned -File .\windows\tests\installer-static.tests.ps1
- name: Install pinned Inno Setup
if: matrix.executable == 'powershell.exe'
shell: pwsh
run: |
$requiredVersion = '6.7.1'
choco upgrade innosetup --version=$requiredVersion --allow-downgrade --no-progress --yes
if ($LASTEXITCODE -ne 0) { throw "Could not install Inno Setup $requiredVersion." }
$iscc = Join-Path ${env:ProgramFiles(x86)} 'Inno Setup 6\ISCC.exe'
if (-not (Test-Path -LiteralPath $iscc -PathType Leaf)) { throw 'ISCC.exe is missing.' }
"ISCC_PATH=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Compile Windows Setup.exe
if: matrix.executable == 'powershell.exe'
shell: pwsh
run: |
$output = Join-Path $env:RUNNER_TEMP 'codex-dream-skin-ci-installer'
& powershell.exe -NoLogo -NoProfile -ExecutionPolicy RemoteSigned `
-File .\windows\installer\build-release.ps1 `
-OutputDirectory $output -IsccPath $env:ISCC_PATH
if ($LASTEXITCODE -ne 0) { throw "Windows release builder failed with exit code $LASTEXITCODE." }
$version = [System.IO.File]::ReadAllText((Resolve-Path .\windows\VERSION)).Trim()
$artifact = Join-Path $output "CodexDreamSkin-Setup-v$version.exe"
if (-not (Test-Path -LiteralPath $artifact -PathType Leaf) -or
(Get-Item -LiteralPath $artifact).Length -le 0) {
throw 'Windows installer artifact is missing or empty.'
}
macos-tests:
name: macOS repository regressions
runs-on: macos-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22"
- name: Locate runner Node.js
id: node
shell: bash
run: echo "path=$(command -v node)" >> "$GITHUB_OUTPUT"
- name: Run macOS regressions without installed-app checks
shell: bash
env:
NODE: ${{ steps.node.outputs.path }}
CODEX_DREAM_SKIN_SKIP_SIGNED_RUNTIME_TESTS: "1"
CODEX_DREAM_SKIN_SKIP_DOCTOR: "1"
run: ./macos/tests/run-tests.sh
- name: Build and test the native menu bar app
run: swift test --package-path macos/menubar-app
- name: Compile and verify the universal DMG
run: ./macos/scripts/build-dmg.sh --skip-tests
- name: Upload DMG artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: CodexDreamSkin-dmg
path: macos/release/*.dmg
retention-days: 7
linux-tests:
name: Linux repository regressions
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "20"
- name: Sync check
shell: bash
run: node tools/sync-runtime-assets.mjs --check
- name: Linux tests
shell: bash
run: bash linux/tests/run-tests.sh
- name: Linux release build
shell: bash
run: bash linux/scripts/build-release-linux.sh
- name: Upload linux artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: linux-packages
path: linux/release/*
if-no-files-found: error