Validate all nine RIDs and NuGet with persistent Woodpecker caches
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
geruipu committed 2026-10-05 17:52:09 +08:00
1 parent 1f23aff5e2
commit 6e5cd77713
4 files changed
+108 -16

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ steps:
- git -C source remote add origin https://git.oeo.one/greepar/StaticLink.Avalonia.git
- git -C source fetch --depth=1 origin "$CI_COMMIT_SHA"
- git -C source checkout --detach FETCH_HEAD
- name: environment-and-linux-x64
- name: nine-platform-build-link-and-pack
image: bash
commands:
- bash source/scripts/woodpecker-cross-test.sh
+4 -1
View File
@@ -173,7 +173,10 @@ def execute(config, tool, incoming):
inputs.append(flag)
if not output:
raise SystemExit("Darwin libtool adapter needs -o")
command = [config["zig"], "ar", "--format=darwin", "rcs", output, *inputs]
libtool = shutil.which('llvm-libtool-darwin') or shutil.which('llvm-libtool-darwin-16')
if not libtool:
raise SystemExit('The pinned image must provide llvm-libtool-darwin to flatten archive dependencies')
command = [libtool, '-static', '-o', output, *inputs]
if tool in ('ar', 'libtool'):
# Never leave a truncated archive behind when disk/network/job failures
# interrupt archiving. GN response files contain a complete member list.
+6 -14
View File
@@ -19,7 +19,7 @@ if [ ! -d "$CACHE_ROOT/source/.git" ]; then
git clone --no-hardlinks "$SCRIPT_ROOT" "$CACHE_ROOT/source"
fi
git -C "$CACHE_ROOT/source" fetch --depth=1 "$SCRIPT_ROOT" HEAD
git -C "$CACHE_ROOT/source" checkout --detach FETCH_HEAD
git -C "$CACHE_ROOT/source" checkout --force --detach FETCH_HEAD
cd "$CACHE_ROOT/source"
cp build/linux-toolchain/sources.lock.json build/linux-toolchain/release.lock.json
mkdir -p "$RESULTS/environment"
@@ -38,7 +38,7 @@ if [ "$AVAILABLE_KB" -lt 41943040 ]; then
fi
echo "Persistent test results: $RESULTS"
exec > >(tee "$RESULTS/build.log") 2>&1
trap 'result=$?; trap - EXIT; if [ "$result" -eq 0 ] && [ -d External/NativeStatic/linux-x64/native ]; then mkdir -p "$RESULTS/native"; cp -a External/NativeStatic/linux-x64/native/. "$RESULTS/native/"; fi; printf "%s\n" "$result" > "$RESULTS/exit-code"; echo "Results retained at $RESULTS"; exit "$result"' EXIT
trap 'result=$?; trap - EXIT; printf "%s\n" "$result" > "$RESULTS/exit-code"; echo "Results retained at $RESULTS"; exit "$result"' EXIT
git rev-parse HEAD > "$RESULTS/commit"
printf '%s\n' "$TOOLCHAIN_IMAGE" > "$RESULTS/toolchain-image"
docker pull "$TOOLCHAIN_IMAGE"
@@ -46,24 +46,16 @@ docker run --rm --user "$(id -u):$(id -g)" \
-e HOME=/tmp -e DOTNET_CLI_HOME=/tmp -e ZIG_GLOBAL_CACHE_DIR=/tmp/zig-cache \
-v "$RESULTS/environment:/validation" --entrypoint python3 \
"$TOOLCHAIN_IMAGE" /opt/staticlink/validate-toolchain.py \
--output /validation --rids '["linux-x64"]'
--output /validation --rids '[]'
mkdir -p External/NativeStatic/.work/home
docker run --rm --user "$(id -u):$(id -g)" \
-e HOME=/src/External/NativeStatic/.work/home -e CROSS_RID \
-e CCACHE_DIR=/src/External/NativeStatic/.work/ccache -e CCACHE_MAXSIZE=1G \
-e ZIG_GLOBAL_CACHE_DIR=/src/External/NativeStatic/.work/zig-global \
-v "$PWD:/src" -w /src --entrypoint bash "$TOOLCHAIN_IMAGE" -c '
-v "$PWD:/src" -v "$RESULTS:/results" -w /src --entrypoint bash "$TOOLCHAIN_IMAGE" -c '
set -euo pipefail
export SOURCE_LOCK=/src/build/linux-toolchain/release.lock.json
source scripts/prepare-cross-sources.sh
BUILD_JOBS="$(nproc)"
echo "Full CPU parallelism: $BUILD_JOBS compilation jobs"
python3 build/linux-toolchain/build-cross.py \
--target "$CROSS_RID" --sources-manifest "$WORK_DIR/cross-sources.json" \
--work /src/External/NativeStatic/.work/toolchains \
--output "/src/External/NativeStatic/zig-cross/$SKIASHARP_VERSION/$CROSS_RID" --jobs "$BUILD_JOBS"
python3 build/linux-toolchain/package-zig.py \
--rid "$CROSS_RID" \
--input "/src/External/NativeStatic/zig-cross/$SKIASHARP_VERSION/$CROSS_RID" \
--output "/src/External/NativeStatic/$CROSS_RID/native"
python3 scripts/woodpecker-nine-platforms.py \
--sources-manifest "$WORK_DIR/cross-sources.json" --results /results
'
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
import argparse
import json
import os
from pathlib import Path
import shutil
import subprocess
import sys
import time
import zipfile
RIDS = (
'osx-arm64', 'osx-x64', 'linux-x64', 'linux-arm64',
'linux-musl-x64', 'linux-musl-arm64', 'win-x64', 'win-x86', 'win-arm64',
)
def run(command, logfile):
print('+', ' '.join(map(str, command)), flush=True)
with logfile.open('a') as output:
process = subprocess.Popen(list(map(str, command)), stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, text=True)
for line in process.stdout:
print(line, end='', flush=True)
output.write(line)
return process.wait()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--sources-manifest', type=Path, required=True)
parser.add_argument('--results', type=Path, required=True)
args = parser.parse_args()
args.results.mkdir(parents=True, exist_ok=True)
lock = json.loads(Path('build/linux-toolchain/release.lock.json').read_text())
jobs = subprocess.check_output(['nproc'], text=True).strip()
report = {'sources': lock, 'jobs': int(jobs), 'targets': {}, 'package': 'not-built',
'runtime_tests': 'not performed; cross compilation and executable linking only'}
descriptor = args.results / 'nine-platform-results.json'
def save():
descriptor.write_text(json.dumps(report, indent=2) + '\n')
save()
for rid in RIDS:
print(f'=== {rid}: compile and link with {jobs} jobs ===', flush=True)
started = time.monotonic()
logfile = args.results / (rid + '.log')
libraries = Path('External/NativeStatic/zig-cross') / lock['skiasharp_version'] / rid
native = Path('External/NativeStatic') / rid / 'native'
command = [sys.executable, 'build/linux-toolchain/build-cross.py',
'--target', rid, '--sources-manifest', args.sources_manifest,
'--work', 'External/NativeStatic/.work/toolchains',
'--output', libraries, '--jobs', jobs]
status = run(command, logfile)
if status == 0:
status = run([sys.executable, 'build/linux-toolchain/package-zig.py',
'--rid', rid, '--input', libraries, '--output', native], logfile)
if status == 0:
shutil.copytree(native, args.results / rid / 'native', dirs_exist_ok=True)
shutil.copytree(libraries / 'link-tests', args.results / rid / 'link-tests',
dirs_exist_ok=True)
report['targets'][rid] = {'exit_code': status, 'passed': status == 0,
'elapsed_seconds': round(time.monotonic() - started, 1)}
save()
print(f'=== {rid}: {"PASS" if status == 0 else "FAIL"} ===', flush=True)
failed = [rid for rid in RIDS if not report['targets'][rid]['passed']]
if failed:
print('Failed platforms: ' + ', '.join(failed), flush=True)
return 1
os.environ['SOURCE_LOCK_JSON'] = json.dumps(lock)
os.environ['PACKAGE_VERSION'] = lock['skiasharp_version'] + '-' + lock['angle_branch'] + '.2'
logfile = args.results / 'pack.log'
status = run([sys.executable, 'scripts/apply-release-version.py'], logfile)
if status == 0:
status = run(['dotnet', 'pack', 'NuGet/StaticGraphics/StaticLink.Avalonia.csproj',
'-c', 'Release', '-o', args.results / 'nuget'], logfile)
if status == 0:
package = next((args.results / 'nuget').glob('*.nupkg'))
with zipfile.ZipFile(package) as archive:
names = set(archive.namelist())
required = {'buildTransitive/StaticLink.Avalonia.props',
'buildTransitive/StaticLink.Avalonia.targets'}
required.update('static/' + rid + '/native/' +
('skia.lib' if rid.startswith('win-') else 'libskia.a') for rid in RIDS)
if not required.issubset(names) or any('\\' in name for name in names):
print('NuGet package is missing target archives or has non-portable paths', flush=True)
status = 1
report['package'] = 'passed' if status == 0 else 'failed'
save()
print('Nine-platform build/link/package: ' + report['package'], flush=True)
return status
if __name__ == '__main__':
raise SystemExit(main())