From 32d3838002baa7e90e66e710f56ea985413d7ec5 Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Mon, 7 Sep 2026 21:50:05 +0200 Subject: [PATCH] =?UTF-8?q?Phase=206:=20Gitea-Cross-Builds,=20Paketpr?= =?UTF-8?q?=C3=BCfung=20und=20gesperrten=20Releasepfad=20implementieren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/INSTALL.txt | 23 + .gitea/scripts/acceptance.py | 37 + .gitea/scripts/bootstrap.sh | 13 + .gitea/scripts/build.py | 62 + .gitea/scripts/distribution.py | 249 ++++ .gitea/scripts/publish.py | 37 + .gitea/scripts/release.py | 130 +++ .gitea/scripts/test_distribution.py | 122 ++ .gitea/workflows/build.yml | 102 ++ .gitea/workflows/publish.yml | 32 + .gitignore | 5 + crates/tb-export/src/bin/tb-template.rs | 17 +- docs/distribution.md | 145 +++ .../design.md | 19 +- .../evidence/clippy.log | 6 + .../evidence/cross-macos-proof/ide-pty.log | 3 + .../evidence/cross-macos-proof/library.log | 1 + .../evidence/cross-macos-proof/native.log | 13 + .../evidence/cross-macos-proof/report.json | 16 + .../evidence/cross-unix-build.log | 270 +++++ .../evidence/cross-windows-build.log | 279 +++++ .../evidence/export-tests.log | 24 + .../evidence/implementation-sha256.json | 12 + .../linux-arm64-proof-final/ide-pty.log | 3 + .../linux-arm64-proof-final/library.log | 1 + .../linux-arm64-proof-final/native.log | 13 + .../linux-arm64-proof-final/report.json | 16 + .../evidence/local-acceptance/acceptance.json | 12 + .../evidence/local-acceptance/acceptance.log | 1005 +++++++++++++++++ .../evidence/local-acceptance/native-ide.log | 12 + .../evidence/openspec.log | 112 ++ .../evidence/package-sha256.json | 6 + .../evidence/release-tests.log | 5 + .../evidence/unix-package.log | 30 + .../evidence/working-tree.patch | 161 +++ .../tasks.md | 18 +- .../verification.md | 111 ++ rust-toolchain.toml | 4 + tests/support/library-abnahme.py | 11 +- tests/support/native-abnahme.py | 8 +- 40 files changed, 3134 insertions(+), 11 deletions(-) create mode 100644 .gitea/INSTALL.txt create mode 100644 .gitea/scripts/acceptance.py create mode 100644 .gitea/scripts/bootstrap.sh create mode 100644 .gitea/scripts/build.py create mode 100644 .gitea/scripts/distribution.py create mode 100644 .gitea/scripts/publish.py create mode 100644 .gitea/scripts/release.py create mode 100644 .gitea/scripts/test_distribution.py create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitea/workflows/publish.yml create mode 100644 docs/distribution.md create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/clippy.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/ide-pty.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/library.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/native.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/report.json create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-unix-build.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-windows-build.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/export-tests.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/implementation-sha256.json create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/ide-pty.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/library.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/native.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/report.json create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.json create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/native-ide.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/openspec.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/package-sha256.json create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/release-tests.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/unix-package.log create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/working-tree.patch create mode 100644 openspec/changes/phase-6-06-gitea-actions-und-releases/verification.md create mode 100644 rust-toolchain.toml diff --git a/.gitea/INSTALL.txt b/.gitea/INSTALL.txt new file mode 100644 index 0000000..80f7101 --- /dev/null +++ b/.gitea/INSTALL.txt @@ -0,0 +1,23 @@ +Terminal Basic — Terminalanwendung + +Archiv in ein eigenes Verzeichnis entpacken. tb und tbc (Windows: .exe) +bleiben neben dem Verzeichnis runtimes// mit tbrt und tbrt.meta +(Windows: tbrt.exe bzw. tbrt.exe.meta). Diese Struktur zusammen aufbewahren. +IDE: ./tb +Windows: .\tb.exe +Ein interaktives Terminal mit RGB-Farben und mindestens 80x25 Zellen ist nötig. + +Beispiel hello.bas: PRINT "Hallo" : END +./tbc check hello.bas +./tbc build hello.bas --exe --target -o hello +./hello +Windows: tbc.exe und hello.exe verwenden. Die Vorlage wird automatisch gefunden. +Target-Triple steht in manifest.json. BASIC-Erzeugung/Linken benötigt keinen +C-/Rust-Compiler oder nativen Linker. Auf macOS muss /usr/bin/codesign für die +lokale Finalisierung verfügbar sein. Das exportierte Executable enthält die +Runtime; benötigte eigene Datendateien liefert das Anwenderprogramm separat. + +Die Pakete sind nicht Developer-ID-/Authenticode-signiert. OS-Vertrauens- +prüfungen bei heruntergeladenen Dateien und Terminalfunktionen bleiben Teil +der Zielabnahme. Build-Baselines sind keine gemessenen minimalen OS-Versionen; +verifizierte Systeme und Einschränkungen stehen im beigefügten Releasenachweis. diff --git a/.gitea/scripts/acceptance.py b/.gitea/scripts/acceptance.py new file mode 100644 index 0000000..1c131d4 --- /dev/null +++ b/.gitea/scripts/acceptance.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +"""Pflichtabnahme mit fixiertem Fremdbestand und zugeordneter Runner-Messung.""" +import json +import os +from pathlib import Path +import platform +import subprocess +import sys +import tempfile +import distribution as dist + +output = Path('acceptance') +output.mkdir() +revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip() +report = dict(revision=revision, passed=False, buildhost=platform.platform(), + run_url=os.environ.get('TB_RUN_URL', ''), foreign=False, inventory=False, + workspace=False, benchmarks=False, native_ide=False) +try: + repo = Path(os.environ['TB_VBDOS_REPO']) + with (output / 'acceptance.log').open('wb') as log: + dist.run([sys.executable, dist.ROOT / 'tests/support/release-abnahme.py', '--vbdos-repo', repo], + stdout=log, stderr=subprocess.STDOUT) + with tempfile.TemporaryDirectory(prefix='tb-ci-runtime-') as temporary: + runtime = Path(temporary) / 'runtime' + with (output / 'native-ide.log').open('wb') as log: + dist.run([sys.executable, dist.ROOT / 'tests/support/build-runtime.py', + '--target', dist.HOSTS[(platform.system(), platform.machine())], + '--output', runtime / dist.HOSTS[(platform.system(), platform.machine())]], + stdout=log, stderr=subprocess.STDOUT) + dist.run(['cargo', 'test', '--locked', '-p', 'tb-cli', '--bin', 'tbc', + 'ide_acceptance::real_native_ide_exports_and_source_free_cli_library_consumer', + '--', '--exact', '--ignored', '--nocapture'], + env=dict(os.environ, TB_IDE_RUNTIME_DIR=str(runtime)), stdout=log, stderr=subprocess.STDOUT) + report.update(passed=True, native_ide=True, foreign=True, inventory=True, workspace=True, benchmarks=True) +finally: + report['log_sha256'] = dist.digest(output / 'acceptance.log') if (output / 'acceptance.log').exists() else None + (output / 'acceptance.json').write_text(json.dumps(report, indent=2) + '\n') diff --git a/.gitea/scripts/bootstrap.sh b/.gitea/scripts/bootstrap.sh new file mode 100644 index 0000000..e7059a8 --- /dev/null +++ b/.gitea/scripts/bootstrap.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -eu +[ "$(uname -sm)" = "Linux aarch64" ] || { echo 'Linux-arm64-Buildhost erforderlich' >&2; exit 1; } +rustup toolchain install 1.97.1 --profile minimal --component clippy --component rustfmt +# Beide per Digest fixierten Cross-Images enthalten Python, Curl, Git und SDK/Clang. +# Separater fester 7-Zip-Download, kein stiller Ersatz durch ZIP oder tar. +curl --fail --location --silent --show-error https://www.7-zip.org/a/7z2501-linux-arm64.tar.xz -o /tmp/tb-7zip.tar.xz +printf '%s %s\n' 39c5140f02ce4436599303c59a149f654cb1bbc47cdc105a942120d747ae040d /tmp/tb-7zip.tar.xz | sha256sum -c - +mkdir -p /tmp/tb-7zip +tar -xJf /tmp/tb-7zip.tar.xz -C /tmp/tb-7zip +install /tmp/tb-7zip/7zz /usr/local/bin/7zz +rustc --version +7zz | head -4 diff --git a/.gitea/scripts/build.py b/.gitea/scripts/build.py new file mode 100644 index 0000000..ecc057f --- /dev/null +++ b/.gitea/scripts/build.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""Ein Cross-Ziel auf dem Linux-arm64-Runner bauen und mit Hostwerkzeug paketieren.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import platform +import subprocess +import distribution as dist + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--target', choices=dist.TARGETS, required=True) + parser.add_argument('--output', type=Path, required=True) + args = parser.parse_args() + dist.require(platform.system() == 'Linux' and platform.machine() == 'aarch64', 'Buildhost muss Linux arm64 sein') + target = args.target + env = dict(os.environ, CARGO_BUILD_JOBS='2', MACOSX_DEPLOYMENT_TARGET='11.0', + CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS='-C target-feature=+crt-static', + XWIN_VERSION='17', XWIN_SDK_VERSION='10.0.26100', XWIN_CRT_VERSION='14.44.17.14') + if target.endswith('msvc'): + builder = ['cargo', 'xwin', 'build'] + build_target = target + else: + builder = ['cargo', 'zigbuild'] + build_target = target + ('.2.28' if target.endswith('linux-gnu') else '') + dist.run(['rustup', 'target', 'add', target]) + dist.run(builder + ['--locked', '--release', '--target', build_target, + '-p', 'tb-ide', '-p', 'tb-cli', '-p', 'tb-runner', '--bins'], cwd=dist.ROOT, env=env) + dist.run(['cargo', 'build', '--locked', '--release', '-p', 'tb-export', '--bin', 'tb-template'], cwd=dist.ROOT, env=env) + cargo_target = Path(os.environ.get('CARGO_TARGET_DIR', dist.ROOT / 'target')).resolve() + metadata = dict(builder=builder[1], build_target=build_target, macos_deployment='11.0') + if target.endswith('msvc'): + # Exakte Header/Library-Bytes pinnen; Microsoft-Kanäle können ihre + # Pakete auch unter derselben SDK-/CRT-Bezeichnung aktualisieren. + cache = Path.home() / '.cache/cargo-xwin/xwin' + checksum = hashlib.sha256() + for path in sorted(cache.rglob('*')): + if path.relative_to(cache).parts[0] not in ('crt', 'sdk'): + continue + if path.is_file() or path.is_symlink(): + checksum.update(path.relative_to(cache).as_posix().encode() + b'\0') + checksum.update((str(path.readlink()).encode() if path.is_symlink() else + hashlib.sha256(path.read_bytes()).digest()) + b'\0') + dist.require(checksum.hexdigest() == '622fb2c2e3560514bfd59b87114c2aea72c15514614e95d01ddae7def96de047', + 'SDK-/CRT-Inhalt weicht vom geprüften Build ab; Pin bewusst aktualisieren') + metadata.update(sdk='10.0.26100', crt='14.44.17.14', sdk_tree_sha256=checksum.hexdigest(), crt_static=True) + os.environ['TB_BUILD_METADATA'] = json.dumps(metadata) + dist.pack(cargo_target / target / 'release', target, args.output.resolve(), cargo_target / 'release/tb-template') + # Abhängigkeiten und Build-Baselines offen ausweisen; das sind keine gemessenen Mindest-OS-Versionen. + with (args.output / (dist.TARGETS[target][0] + '-build.txt')).open('w') as log: + for command in (['uname', '-a'], ['rustc', '-vV'], ['cargo', '--version']): + subprocess.run(command, stdout=log, stderr=subprocess.STDOUT, check=True) + log.write(f'image={os.environ.get("TB_BUILD_IMAGE", "local")}\n' + f'build_target={build_target}\nMACOSX_DEPLOYMENT_TARGET=11.0\n' + 'XWIN_VERSION=17\nXWIN_SDK_VERSION=10.0.26100\nXWIN_CRT_VERSION=14.44.17.14\n') + + +if __name__ == '__main__': + main() diff --git a/.gitea/scripts/distribution.py b/.gitea/scripts/distribution.py new file mode 100644 index 0000000..32156b7 --- /dev/null +++ b/.gitea/scripts/distribution.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +"""Vierzielpakete bauen, entpackt prüfen und vollständige Freigaben validieren.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import platform +import re +import shutil +import subprocess +import sys +import tarfile +import tempfile +import tomllib + +ROOT = Path(__file__).resolve().parents[2] +TARGETS = { + 'x86_64-pc-windows-msvc': ('windows-amd64', '.7z'), + 'aarch64-apple-darwin': ('macos-arm64', '.tar.gz'), + 'x86_64-unknown-linux-gnu': ('linux-amd64', '.tar.gz'), + 'aarch64-unknown-linux-gnu': ('linux-arm64', '.tar.gz'), +} +HOSTS = {('Windows', 'AMD64'): list(TARGETS)[0], ('Darwin', 'arm64'): list(TARGETS)[1], + ('Linux', 'x86_64'): list(TARGETS)[2], ('Linux', 'aarch64'): list(TARGETS)[3]} +TBL_SHA = '5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df' + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def run(command, **kwargs): + print('+', ' '.join(map(str, command)), flush=True) + return subprocess.run(list(map(str, command)), check=True, timeout=3600, **kwargs) + + +def name(version, target): + require(re.fullmatch(r'[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9.-]+)?', version), 'Ungültige Paketversion') + label, extension = TARGETS[target] + return f'terminalbasic-{version}-{label}{extension}' + + +def sevenzip(): + tool = shutil.which('7zz') or shutil.which('7z') + require(tool, '7-Zip fehlt; Windows erfordert echte .7z-Archive') + return tool + + +def programs(target): + suffix = '.exe' if target == list(TARGETS)[0] else '' + return ['tb' + suffix, 'tbc' + suffix, f'runtimes/{target}/tbrt' + suffix] + + +def files(target): + return set(programs(target) + [programs(target)[2] + '.meta', 'LICENSE', 'INSTALL.txt', 'manifest.json']) + + +def unpack(archive, dest, target): + """Nur bekannte reguläre Dateien; keine Symlinks, Unterverzeichnisse oder Traversierung.""" + if archive.name.endswith('.7z'): + listing = subprocess.check_output([sevenzip(), 'l', '-slt', '--', str(archive)], text=True) + members = listing.split('----------\n', 1)[-1].strip().split('\n\n') + found = set() + for member in members: + fields = dict(line.split(' = ', 1) for line in member.splitlines() if ' = ' in line) + path = fields.get('Path') + require(path in files(target) and path not in found, f'Unerlaubter Archiveintrag: {path}') + require(fields.get('Folder', '-') == '-' and not fields.get('Symbolic Link') and + not fields.get('Hard Link') and not fields.get('Attributes', '').startswith('D'), 'Archivlink/-verzeichnis') + found.add(path) + require(found == files(target), 'Unvollständiges 7z-Archiv') + run([sevenzip(), 'x', '-y', '-o' + str(dest), '--', archive], stdout=subprocess.DEVNULL) + else: + with tarfile.open(archive, 'r:gz') as tar: + members = tar.getmembers() + require(len(members) == len(files(target)) and {m.name for m in members} == files(target), 'Falscher Archivinhalt') + require(all(m.isfile() for m in members), 'Nur reguläre Dateien erlaubt') + for member in members: + data = tar.extractfile(member).read() + path = dest / member.name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(data) + path.chmod(member.mode & 0o777) + require({p.relative_to(dest).as_posix() for p in dest.rglob('*') if p.is_file()} == files(target), 'Falscher entpackter Inhalt') + require(all(not p.is_symlink() and (p.is_file() or p.is_dir()) for p in dest.rglob('*')), 'Unerlaubter Dateityp') + + +def verify(archive, target, inspector=None): + with tempfile.TemporaryDirectory(prefix='tb-package-') as temp: + dest = Path(temp) + unpack(archive, dest, target) + manifest = json.loads((dest / 'manifest.json').read_text()) + require(manifest['target'] == target and archive.name == name(manifest['version'], target), 'Falsches Paketziel/-version') + require(set(manifest['files']) == files(target) - {'manifest.json'}, 'Falsches Dateimanifest') + for path, sha in manifest['files'].items(): + require(digest(dest / path) == sha, f'Beschädigte Datei: {path}') + for binary in programs(target): + if inspector: + run([inspector, '--inspect', dest / binary, target], stdout=subprocess.DEVNULL) + if target != list(TARGETS)[0]: + require((dest / binary).stat().st_mode & 0o111 == 0o111, 'Executable-Rechte fehlen') + metadata = (dest / (programs(target)[2] + '.meta')).read_text() + require(f'target={target}\n' in metadata and f'package={manifest["version"]}\n' in metadata, 'Vorlagenversion/-ziel falsch') + return manifest + + +def pack(binary_dir, target, output, inspector): + version = tomllib.loads((ROOT / 'Cargo.toml').read_text())['workspace']['package']['version'] + revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=ROOT, text=True).strip() + output.mkdir(parents=True, exist_ok=True) + archive = output / name(version, target) + require(not archive.exists(), f'Paket existiert bereits: {archive}') + with tempfile.TemporaryDirectory(prefix='tb-pack-') as temp: + stage = Path(temp) + for binary in programs(target): + run([inspector, '--inspect', binary_dir / Path(binary).name, target], stdout=subprocess.DEVNULL) + (stage / binary).parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(binary_dir / Path(binary).name, stage / binary) + (stage / binary).chmod(0o755) + run([inspector, stage / programs(target)[2], target]) + shutil.copyfile(ROOT / 'LICENSE', stage / 'LICENSE') + shutil.copyfile(ROOT / '.gitea/INSTALL.txt', stage / 'INSTALL.txt') + manifest = dict(version=version, revision=revision, target=target, + buildhost=platform.platform(), rustc=subprocess.check_output(['rustc', '--version'], text=True).strip(), + build_image=os.environ.get('TB_BUILD_IMAGE', 'local'), + cross_toolchain=json.loads(os.environ.get('TB_BUILD_METADATA', '{}')), + source_dirty=bool(subprocess.check_output(['git', 'status', '--porcelain'], cwd=ROOT)), + files={p.relative_to(stage).as_posix(): digest(p) for p in stage.rglob('*') if p.is_file()}) + (stage / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n') + if target == list(TARGETS)[0]: + run([sevenzip(), 'a', '-t7z', archive, *sorted(files(target))], cwd=stage, stdout=subprocess.DEVNULL) + else: + with tarfile.open(archive, 'w:gz') as tar: + for filename in sorted(files(target)): + tar.add(stage / filename, arcname=filename) + verify(archive, target, inspector) + (output / (archive.name + '.sha256')).write_text(f'{digest(archive)} {archive.name}\n') + print(archive) + + +def target_check(archive, target, output, windows_console_test=None): + require(HOSTS.get((platform.system(), platform.machine())) == target, 'Echte Zielausführung erfordert passendes Hostsystem') + require(not output.exists(), 'Nachweis existiert bereits') + manifest = verify(archive, target) + report = dict(target=target, revision=manifest['revision'], package=archive.name, + package_sha256=digest(archive), tbl_sha256=TBL_SHA, host=platform.platform(), + automated_passed=False, manual_terminal_passed=False, checks={}) + output.mkdir(parents=True) + try: + with tempfile.TemporaryDirectory(prefix='tb-unpacked-') as temp: + dest = Path(temp) + unpack(archive, dest, target) + env = dict(os.environ, PATH='') + run([dest / programs(target)[0], '--help'], cwd=dest, env=env, stdout=subprocess.DEVNULL) + source = dest / 'hello.bas'; source.write_text('PRINT 42\nEND\n') + executable = dest / ('hello.exe' if os.name == 'nt' else 'hello') + run([dest / programs(target)[1], 'build', source, '--exe', '--target', target, '-o', executable], cwd=dest, env=env) + source.unlink() + actual = subprocess.check_output([str(executable)], cwd=dest, env=env, timeout=30) + require(actual.replace(b'\r\n', b'\n') == b' 42 \n', 'Standard-Vorlagenpfad funktioniert nicht') + report['checks']['default-template'] = 'passed' + commands = { + 'native': [sys.executable, ROOT / 'tests/support/native-abnahme.py', '--bin-dir', dest, '--target', target], + 'library': [sys.executable, ROOT / 'tests/support/library-abnahme.py', '--bin-dir', dest], + } + if os.name == 'posix': + commands['ide-pty'] = [sys.executable, ROOT / 'tests/support/ide-execution-pty.py', '--binary', dest / 'tb'] + if os.name == 'nt': + require(windows_console_test and windows_console_test.is_file(), 'Windows-Konsolentest fehlt') + report['windows_console_test_sha256'] = digest(windows_console_test) + commands['windows-console'] = [windows_console_test, '--exact', + 'terminal::tests::windows_console_restores_modes', '--ignored', '--nocapture'] + for check, command in commands.items(): + with (output / (check + '.log')).open('wb') as log: + run(command, cwd=dest, stdout=log, stderr=subprocess.STDOUT) + report['checks'][check] = 'passed' + report['automated_passed'] = True + finally: + require(digest(archive) == report['package_sha256'], 'Paket während Zielprüfung verändert') + (output / 'report.json').write_text(json.dumps(report, indent=2) + '\n') + + +def gate(directory, evidence, revision, version): + """Fail closed: vier exakte Pakete und unabhängige, passende Zielnachweise.""" + require(re.fullmatch('[0-9a-f]{40}', revision), 'Ungültige Revision') + require(digest(ROOT / 'tests/libraries/portable.tbl') == TBL_SHA, 'TBL-Probe verändert') + assets = [] + for target in TARGETS: + archive = directory / name(version, target) + require(archive.is_file(), f'Pflichtpaket fehlt: {archive.name}') + sha = digest(archive) + checksum = archive.with_name(archive.name + '.sha256') + require(checksum.read_text() == f'{sha} {archive.name}\n', 'Paketprüfsumme falsch') + manifest = verify(archive, target, ROOT / 'target/release/tb-template') + require(manifest['revision'] == revision and not manifest['source_dirty'], 'Paket aus falschem/uncommittetem Stand') + proof = json.loads((evidence / target / 'report.json').read_text()) + require(proof.get('target') == target and proof.get('revision') == revision and proof.get('package') == archive.name and + proof.get('package_sha256') == sha and proof.get('tbl_sha256') == TBL_SHA, 'Zielnachweis passt nicht zum Paket') + required = {'native', 'library', 'default-template', 'windows-console' if target == list(TARGETS)[0] else 'ide-pty'} + require(proof.get('automated_passed') is True and all(proof.get('checks', {}).get(k) == 'passed' for k in required), 'Automatisierte Zielprüfung fehlt') + manual = json.loads((evidence / target / 'manual.json').read_text()) + require(manual.get('revision') == revision and manual.get('package_sha256') == sha and + manual.get('target') == target and manual.get('passed') is True and + manual.get('tester') and manual.get('terminal_versions') and manual.get('evidence'), 'Manueller Terminalnachweis fehlt') + terminals = {'windows-terminal'} if target == list(TARGETS)[0] else {'terminal.app'} if target == list(TARGETS)[1] else {'xterm', 'vte'} + require(isinstance(manual['terminal_versions'], dict) and + all(manual['terminal_versions'].get(t) for t in terminals), 'Pflichtemulator/Version fehlt') + require(all(manual.get('cases', {}).get(k) is True for k in + ('f1_f12', 'modifiers', 'mouse', 'unicode_colors', 'resize', 'input_break', 'shell')), 'Manuelle Pflichtfolge unvollständig') + for reference in manual['evidence']: + relative = Path(reference) + require(not relative.is_absolute() and '..' not in relative.parts, 'Ungültiger manueller Nachweispfad') + path = evidence / target / relative + require(path.is_file() and path.stat().st_size > 0, 'Manueller Beleg fehlt') + assets.extend([archive, checksum]) + acceptance = json.loads((evidence / 'acceptance.json').read_text()) + require(acceptance.get('revision') == revision and acceptance.get('passed') is True and + all(acceptance.get(k) for k in ('foreign', 'inventory', 'workspace', 'benchmarks', 'native_ide', 'run_url', 'buildhost')), 'Pflichtabnahme/Benchmarks fehlen') + return assets + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest='command', required=True) + p = sub.add_parser('pack'); p.add_argument('--bin-dir', type=Path, required=True); p.add_argument('--output', type=Path, required=True) + p.add_argument('--inspector', type=Path, required=True); p.add_argument('--target', choices=TARGETS, required=True) + for command in ('verify', 'target-check'): + p = sub.add_parser(command); p.add_argument('--archive', type=Path, required=True); p.add_argument('--target', choices=TARGETS, required=True) + if command == 'verify': p.add_argument('--inspector', type=Path) + else: + p.add_argument('--output', type=Path, required=True) + p.add_argument('--windows-console-test', type=Path) + p = sub.add_parser('gate'); p.add_argument('--packages', type=Path, required=True); p.add_argument('--evidence', type=Path, required=True) + p.add_argument('--revision', required=True); p.add_argument('--version', required=True) + args = parser.parse_args() + if args.command == 'pack': pack(args.bin_dir.resolve(), args.target, args.output.resolve(), args.inspector.resolve()) + elif args.command == 'verify': verify(args.archive.resolve(), args.target, args.inspector.resolve() if args.inspector else None) + elif args.command == 'target-check': target_check(args.archive.resolve(), args.target, args.output.resolve(), args.windows_console_test.resolve() if args.windows_console_test else None) + else: gate(args.packages, args.evidence, args.revision, args.version) + + +if __name__ == '__main__': + main() diff --git a/.gitea/scripts/publish.py b/.gitea/scripts/publish.py new file mode 100644 index 0000000..b670310 --- /dev/null +++ b/.gitea/scripts/publish.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +"""Nur einen bestehenden Tag und Nachweise aus einer Origin-Revision verwenden.""" +import os +from pathlib import Path +import re +import subprocess +import tempfile +import distribution as dist +import release + +tag, evidence_revision = os.environ['TB_TAG'], os.environ['TB_EVIDENCE_REVISION'] +dist.require(re.fullmatch(r'v[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9.-]+)?', tag), 'Ungültiger Tag') +dist.require(re.fullmatch('[0-9a-f]{40}', evidence_revision), 'Ungültige Nachweisrevision') +revision = subprocess.check_output(['git', 'rev-parse', '--verify', tag + '^{commit}'], text=True).strip() +api = release.Gitea() +info = api.request('GET', '/git/commits/' + evidence_revision) +dist.require(info['sha'] == evidence_revision, 'Nachweise nicht am Origin') +# Checkout enthält alle Origin-Branches. Ein nicht vorhandener Commit scheitert hier. +base = f'release-evidence/{tag}' +names = subprocess.check_output(['git', 'ls-tree', '-r', '--name-only', evidence_revision, base], text=True).splitlines() +with tempfile.TemporaryDirectory(prefix='tb-release-') as tmp: + evidence = Path(tmp) / 'evidence'; evidence.mkdir() + for name in names: + relative = Path(name).relative_to(base) + dist.require('..' not in relative.parts and not relative.is_absolute(), 'Ungültiger Nachweispfad') + path = evidence / relative; path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(subprocess.check_output(['git', 'show', evidence_revision + ':' + name])) + packages = Path(tmp) / 'packages'; packages.mkdir() + draft = api.request('GET', '/releases/tags/' + tag) + wanted = release.expected(tag[1:]) + dist.require(draft['draft'] and len(draft.get('assets', [])) == len(wanted) and + {a['name'] for a in draft['assets']} == set(wanted), 'Unvollständiger Entwurf') + for asset in draft['assets']: + (packages / asset['name']).write_bytes(api.download(asset)) + # Grundabnahme kommt aus dem ursprünglichen Taglauf, nicht aus manuell ersetzten Angaben. + (evidence / 'acceptance.json').write_bytes((packages / 'acceptance.json').read_bytes()) + release.publish(api, packages, evidence, tag, revision) diff --git a/.gitea/scripts/release.py b/.gitea/scripts/release.py new file mode 100644 index 0000000..fabdf56 --- /dev/null +++ b/.gitea/scripts/release.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""Gitea-Entwurf befüllen; erst nach exakten Paket-/Zielnachweisen freigeben.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +from urllib.error import HTTPError +from urllib.parse import quote, urlparse +from urllib.request import Request, HTTPRedirectHandler, build_opener +import distribution as dist + + +class SafeRedirect(HTTPRedirectHandler): + def redirect_request(self, req, fp, code, msg, headers, newurl): + redirected = super().redirect_request(req, fp, code, msg, headers, newurl) + if redirected and urlparse(newurl).netloc != urlparse(req.full_url).netloc: + redirected.remove_header('Authorization') + return redirected + + +class Gitea: + def __init__(self): + self.base = os.environ['GITEA_SERVER_URL'].rstrip('/') + dist.require(self.base == 'https://git.rfc1437.de', 'Release nur am bestehenden Origin') + dist.require(os.environ['GITEA_REPOSITORY'] == 'hugo/TerminalBasic', 'Falsches Release-Repository') + self.api = self.base + '/api/v1/repos/hugo/TerminalBasic' + self.token = os.environ['TB_RELEASE_TOKEN'] + self.open = build_opener(SafeRedirect()).open + + def request(self, method, path, data=None): + raw = isinstance(data, bytes) + headers = {'Authorization': 'token ' + self.token, + 'Content-Type': 'application/octet-stream' if raw else 'application/json'} + payload = data if raw or data is None else json.dumps(data).encode() + with self.open(Request(self.api + path, data=payload, headers=headers, method=method), timeout=120) as response: + return json.load(response) + + def download(self, asset): + url = asset['browser_download_url'] + dist.require(urlparse(url).netloc == urlparse(self.base).netloc, 'Fremder Assetserver') + with self.open(Request(url, headers={'Authorization': 'token ' + self.token}), timeout=120) as response: + return response.read() + + +def expected(version): + return [n for t in dist.TARGETS for n in (dist.name(version, t), dist.name(version, t) + '.sha256')] + ['acceptance.json'] + + +def stage(api, directory, tag, revision): + version = tag.removeprefix('v') + dist.require(tag == 'v' + version and re.fullmatch('[0-9a-f]{40}', revision), 'Tag/Revision ungültig') + dist.require(api.request('GET', '/tags/' + quote(tag, safe=''))['commit']['sha'] == revision, 'Tag zeigt auf andere Revision') + names = expected(version) + for target in dist.TARGETS: + path = directory / dist.name(version, target) + manifest = dist.verify(path, target, dist.ROOT / 'target/release/tb-template') + dist.require(manifest['revision'] == revision and not manifest['source_dirty'], 'Paketrevision falsch/uncommitted') + dist.require(path.with_name(path.name + '.sha256').read_text() == f'{dist.digest(path)} {path.name}\n', 'Paketprüfsumme falsch') + acceptance = json.loads((directory / 'acceptance.json').read_text()) + dist.require(acceptance.get('revision') == revision and acceptance.get('passed') is True, 'Grundabnahme fehlt') + try: + release = api.request('GET', '/releases/tags/' + quote(tag, safe='')) + except HTTPError as error: + if error.code != 404: + raise + release = api.request('POST', '/releases', dict(tag_name=tag, target_commitish=revision, + name='Terminal Basic ' + version, draft=True, + body='Vierzielpakete im Entwurf. Zielnachweise fehlen noch; keine Freigabe.')) + dist.require(release['draft'], 'Bereits veröffentlichten Release nicht verändern') + # Wiederholungen dürfen identische Uploads ergänzen, keine vorhandenen Assets ersetzen. + existing = {a['name']: a for a in release.get('assets', [])} + dist.require(set(existing) <= set(names), 'Unerwartete Assets im Entwurf') + for name in names: + data = (directory / name).read_bytes() + if name in existing: + dist.require(api.download(existing[name]) == data, f'Abweichendes vorhandenes Asset: {name}') + else: + api.request('POST', f'/releases/{release["id"]}/assets?name=' + quote(name), data) + verify_uploads(api, release['id'], directory, names) + return release['id'] + + +def verify_uploads(api, release_id, directory, names): + release = api.request('GET', f'/releases/{release_id}') + assets = release.get('assets', []) + dist.require(len(assets) == len(names) and {a['name'] for a in assets} == set(names), 'Unvollständiger Asset-Upload') + for asset in assets: + dist.require(hashlib.sha256(api.download(asset)).hexdigest() == dist.digest(directory / asset['name']), 'Uploadprüfsumme falsch') + return release + + +def publish(api, directory, evidence, tag, revision): + version = tag.removeprefix('v') + dist.require(tag == 'v' + version, 'Versionstag erforderlich') + dist.require(api.request('GET', '/tags/' + quote(tag, safe=''))['commit']['sha'] == revision, 'Tag zeigt auf andere Revision') + dist.gate(directory, evidence, revision, version) + release = api.request('GET', '/releases/tags/' + quote(tag, safe='')) + verify_uploads(api, release['id'], directory, expected(version)) + dist.require(release['draft'], 'Bereits freigegebenen Release nicht verändern') + api.request('PATCH', f'/releases/{release["id"]}', dict(draft=False, + body=f'Geprüfte Vierzielpakete für Revision {revision}. Zugehörige Zielnachweise: {os.environ.get("TB_EVIDENCE_REVISION", "lokaler Nachweissatz")}.')) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('command', choices=['stage', 'download', 'publish']) + parser.add_argument('--packages', type=Path, required=True) + parser.add_argument('--tag', required=True); parser.add_argument('--revision', required=True) + parser.add_argument('--evidence', type=Path) + args = parser.parse_args() + api = Gitea() + if args.command == 'stage': stage(api, args.packages, args.tag, args.revision) + elif args.command == 'publish': + dist.require(args.evidence, '--evidence erforderlich') + publish(api, args.packages, args.evidence, args.tag, args.revision) + else: + args.packages.mkdir(parents=True) # Nie lokale Kandidaten überschreiben. + release = api.request('GET', '/releases/tags/' + quote(args.tag, safe='')) + names = expected(args.tag.removeprefix('v')) + dist.require(release['draft'], 'Nur bestehende Entwürfe freigeben') + assets = release.get('assets', []) + dist.require(len(assets) == len(names) and {a['name'] for a in assets} == set(names), 'Pflichtassets fehlen') + for asset in assets: + (args.packages / asset['name']).write_bytes(api.download(asset)) + + +if __name__ == '__main__': + main() diff --git a/.gitea/scripts/test_distribution.py b/.gitea/scripts/test_distribution.py new file mode 100644 index 0000000..1e6abca --- /dev/null +++ b/.gitea/scripts/test_distribution.py @@ -0,0 +1,122 @@ +import copy +import hashlib +import json +from pathlib import Path +import tarfile +import tempfile +import unittest +from unittest.mock import patch +import distribution as d +import release as r + + +class DistributionTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.root = Path(self.temp.name) + self.packages = self.root / 'packages'; self.packages.mkdir() + self.evidence = self.root / 'evidence'; self.evidence.mkdir() + self.revision = 'a' * 40 + self.version = '0.1.0' + self.manifests = {} + for target in d.TARGETS: + path = self.packages / d.name(self.version, target) + path.write_bytes(target.encode()) + path.with_name(path.name + '.sha256').write_text(f'{d.digest(path)} {path.name}\n') + self.manifests[target] = dict(revision=self.revision, version=self.version, source_dirty=False) + proof = self.evidence / target; proof.mkdir() + report = dict(target=target, revision=self.revision, package=path.name, + package_sha256=d.digest(path), tbl_sha256=d.TBL_SHA, automated_passed=True, + checks={k:'passed' for k in ('native','library','ide-pty','windows-console','default-template')}) + (proof / 'report.json').write_text(json.dumps(report)) + (proof / 'manual.json').write_text(json.dumps(dict(target=target, revision=self.revision, + package_sha256=d.digest(path), passed=True, tester='Prüfer', + terminal_versions={k:'Version 1' for k in ('windows-terminal','terminal.app','xterm','vte')}, + cases={k:True for k in ('f1_f12','modifiers','mouse','unicode_colors','resize','input_break','shell')}, evidence=['terminal.txt']))) + (proof / 'terminal.txt').write_text('Bedienprotokoll') + acceptance = dict(revision=self.revision, passed=True, foreign=True, inventory=True, + workspace=True, benchmarks=True, native_ide=True, run_url='https://git.rfc1437.de/run/1', buildhost='Linux arm64') + for directory in (self.packages, self.evidence): + (directory / 'acceptance.json').write_text(json.dumps(acceptance)) + self.mock_verify = patch.object(d, 'verify', side_effect=lambda archive, target, *args: self.manifests[target]) + self.mock_verify.start(); self.addCleanup(self.mock_verify.stop) + + def gate(self): + return d.gate(self.packages, self.evidence, self.revision, self.version) + + def test_complete_gate_and_missing_or_wrong_evidence(self): + self.assertEqual(len(self.gate()), 8) + target = list(d.TARGETS)[0] + path = self.evidence / target / 'report.json' + valid = json.loads(path.read_text()) + for key, value in [('revision','b'*40), ('target',list(d.TARGETS)[1]), ('package_sha256','0'*64), + ('tbl_sha256','0'*64), ('automated_passed',False), ('checks',{'native':'passed'})]: + broken = dict(valid, **{key:value}); path.write_text(json.dumps(broken)) + with self.assertRaises(ValueError, msg=key): self.gate() + path.write_text(json.dumps(valid)) + (self.evidence / target / 'manual.json').unlink() + with self.assertRaises(FileNotFoundError): self.gate() + + def test_missing_corrupt_dirty_and_mismatched_packages(self): + first = next(iter(d.TARGETS)) + self.manifests[first]['source_dirty'] = True + with self.assertRaises(ValueError): self.gate() + self.manifests[first]['source_dirty'] = False + path = self.packages / d.name(self.version, first) + path.write_bytes(b'broken') + with self.assertRaises(ValueError): self.gate() + path.unlink() + with self.assertRaises(ValueError): self.gate() + + def test_archive_traversal_rejected_before_extract(self): + path = self.root / 'evil.tar.gz' + with tarfile.open(path, 'w:gz') as tar: + entry = tarfile.TarInfo('../escape'); tar.addfile(entry) + dest = self.root / 'unpack'; dest.mkdir() + with self.assertRaises(ValueError): d.unpack(path, dest, list(d.TARGETS)[1]) + self.assertFalse((self.root / 'escape').exists()) + + def test_upload_failure_never_publishes_or_overwrites(self): + class API: + def __init__(self): + self.release = dict(id=1, draft=True, assets=[]) + self.data = {}; self.fail_at = None; self.writes = [] + def request(self, method, path, data=None): + if path.startswith('/tags/'): return {'commit': {'sha': 'a'*40}} + if method == 'GET': return copy.deepcopy(self.release) + self.writes.append((method,path)) + if method == 'POST': + name = path.split('name=')[1] + if name == self.fail_at: raise OSError('simulierter Uploadfehler') + self.data[name] = data + self.release['assets'].append(dict(name=name, browser_download_url=name)) + return {} + if method == 'PATCH': self.release.update(data) + def download(self, asset): return self.data[asset['name']] + api = API(); api.fail_at = r.expected(self.version)[2] + with self.assertRaises(OSError): r.stage(api, self.packages, 'v'+self.version, self.revision) + self.assertTrue(api.release['draft']) + self.assertFalse(any(method=='PATCH' for method,_ in api.writes)) + api.fail_at = None + r.stage(api, self.packages, 'v'+self.version, self.revision) + r.publish(api, self.packages, self.evidence, 'v'+self.version, self.revision) + self.assertFalse(api.release['draft']) + before = list(api.writes) + with self.assertRaises(ValueError): r.stage(api, self.packages, 'v'+self.version, self.revision) + self.assertEqual(before, api.writes) + + def test_incomplete_remote_upload_blocks_publish(self): + class API: + def request(self, method, path, data=None): + self.assert_get(method) + if path.startswith('/tags/'): return {'commit': {'sha': 'a'*40}} + return dict(id=1, draft=True, assets=[]) + @staticmethod + def assert_get(method): + if method != 'GET': raise AssertionError('Unerwartete Mutation') + with self.assertRaises(ValueError): r.publish(API(), self.packages, self.evidence, 'v'+self.version, self.revision) + + +if __name__ == '__main__': + unittest.main() diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..cd79e35 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,102 @@ +name: Vierziel-Build und Pflichtabnahme +on: + push: + branches: ['main', 'ci/**'] + tags: ['v*'] + pull_request: + workflow_dispatch: +permissions: + contents: read +jobs: + checks: + if: gitea.event_name != 'pull_request' || gitea.event.pull_request.head.repo.full_name == gitea.repository + runs-on: linux-arm64 + container: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + timeout-minutes: 60 + env: + CARGO_BUILD_JOBS: '2' + TB_VBDOS_REPOSITORY: ${{ vars.TB_VBDOS_REPOSITORY }} + TB_VBDOS_REPO: /tmp/tb-vbdos + TB_RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_number }} + steps: + - uses: https://gitea.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + persist-credentials: false + - name: Gepinnte Werkzeuge + run: sh .gitea/scripts/bootstrap.sh + - name: Fixierten Fremdbestand bereitstellen + run: | + set -eu + test -n "$TB_VBDOS_REPOSITORY" || { echo 'TB_VBDOS_REPOSITORY für Pflichtabnahme fehlt'; exit 1; } + git init "$TB_VBDOS_REPO" + git -C "$TB_VBDOS_REPO" fetch --depth=1 "$TB_VBDOS_REPOSITORY" 1cdd2b32b829fe1721d0b6aecc433abc47a96fb6 + git -C "$TB_VBDOS_REPO" checkout --detach FETCH_HEAD + - name: Paket- und Release-Regressionen + run: python3 -m unittest discover -s .gitea/scripts -p 'test_*.py' + - name: Workspace, Inventar, Fremdprogramme und Referenzbenchmarks + run: python3 .gitea/scripts/acceptance.py + - uses: https://gitea.com/actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 + if: always() + with: + name: acceptance + path: acceptance/ + if-no-files-found: error + build: + if: gitea.event_name != 'pull_request' || gitea.event.pull_request.head.repo.full_name == gitea.repository + runs-on: linux-arm64 + timeout-minutes: 90 + strategy: + fail-fast: false + max-parallel: 1 + matrix: + include: + - target: x86_64-pc-windows-msvc + image: messense/cargo-xwin@sha256:4696dd4e79edf8569fa99c4b06bd99273e0501c7adc983aa61d57945f795bef0 + - target: aarch64-apple-darwin + image: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + - target: x86_64-unknown-linux-gnu + image: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + - target: aarch64-unknown-linux-gnu + image: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + container: ${{ matrix.image }} + env: + TB_BUILD_IMAGE: ${{ matrix.image }} + TB_TARGET: ${{ matrix.target }} + steps: + - uses: https://gitea.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + persist-credentials: false + - run: sh .gitea/scripts/bootstrap.sh + - name: Bauen, Format prüfen und paketieren + run: python3 .gitea/scripts/build.py --target "$TB_TARGET" --output dist + - uses: https://gitea.com/actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 + with: + name: packages-${{ matrix.target }} + path: dist/ + if-no-files-found: error + stage: + if: startsWith(gitea.ref, 'refs/tags/v') && gitea.event_name == 'push' + needs: [checks, build] + runs-on: linux-arm64 + container: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + steps: + - uses: https://gitea.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + persist-credentials: false + - run: sh .gitea/scripts/bootstrap.sh + - uses: https://gitea.com/actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a + with: + path: artifacts + - run: cargo build --locked --release -p tb-export --bin tb-template + - name: Vollständigen Releaseentwurf erstellen + env: + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} + TB_RELEASE_TOKEN: ${{ secrets.TB_RELEASE_TOKEN }} + TB_TAG: ${{ gitea.ref_name }} + TB_REVISION: ${{ gitea.sha }} + run: | + mkdir packages + cp artifacts/packages-*/*.7z artifacts/packages-*/*.tar.gz artifacts/packages-*/*.sha256 packages/ + cp artifacts/acceptance/acceptance.json packages/ + python3 .gitea/scripts/release.py stage --packages packages --tag "$TB_TAG" --revision "$TB_REVISION" diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml new file mode 100644 index 0000000..6a413a4 --- /dev/null +++ b/.gitea/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Geprüften Gitea-Entwurf freigeben +on: + workflow_dispatch: + inputs: + tag: + description: 'Vorhandener Versionstag, z.B. v0.1.0' + required: true + evidence_commit: + description: '40-stellige Origin-Revision mit release-evidence//' + required: true +permissions: + contents: read +jobs: + publish: + if: gitea.ref == 'refs/heads/main' + runs-on: linux-arm64 + container: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b + steps: + - uses: https://gitea.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + fetch-depth: 0 + persist-credentials: false + - run: sh .gitea/scripts/bootstrap.sh + - run: cargo build --locked --release -p tb-export --bin tb-template + - name: Originalpakete und revisionsgebundene Zielnachweise prüfen + env: + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} + TB_RELEASE_TOKEN: ${{ secrets.TB_RELEASE_TOKEN }} + TB_TAG: ${{ inputs.tag }} + TB_EVIDENCE_REVISION: ${{ inputs.evidence_commit }} + run: python3 .gitea/scripts/publish.py diff --git a/.gitignore b/.gitignore index b7141ea..15c6f97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ /target **/*.rs.bk *.pdb +/dist +/acceptance +/artifacts +/packages +**/__pycache__ diff --git a/crates/tb-export/src/bin/tb-template.rs b/crates/tb-export/src/bin/tb-template.rs index 7776b1a..c1ed101 100644 --- a/crates/tb-export/src/bin/tb-template.rs +++ b/crates/tb-export/src/bin/tb-template.rs @@ -1,10 +1,23 @@ //! Builder-Hilfe: geprüfte Metadaten für eine frisch gebaute Runtime schreiben. fn main() -> anyhow::Result<()> { - let args: Vec<_> = std::env::args().skip(1).collect(); + let mut args: Vec<_> = std::env::args().skip(1).collect(); + let inspect = args.first().is_some_and(|s| s == "--inspect"); + if inspect { + args.remove(0); + } anyhow::ensure!( args.len() == 2, - "Aufruf: tb-template " + "Aufruf: tb-template [--inspect] " ); + if inspect { + let found = tb_export::native_target(&std::fs::read(&args[0])?)?; + anyhow::ensure!( + found == tb_export::Target::parse(&args[1])?, + "Executable hat falsches Ziel" + ); + println!("{}", found.triple()); + return Ok(()); + } tb_export::prepare_template( std::path::Path::new(&args[0]), tb_export::Target::parse(&args[1])?, diff --git a/docs/distribution.md b/docs/distribution.md new file mode 100644 index 0000000..c42695f --- /dev/null +++ b/docs/distribution.md @@ -0,0 +1,145 @@ +# Gitea-Build und Distribution + +Change 06 baut ausschließlich am Origin `git.rfc1437.de/hugo/TerminalBasic`. +Die Actions verwenden das bestätigte Label `linux-arm64` und vier Zieltriple. +Kein Cross-Build ist ein Windows-/macOS-/Linux-Emulatornachweis. + +## Buildumgebung + +| Ziel | Builder | Fixierte Baseline | +|---|---|---| +| Windows amd64 | cargo-xwin 0.23.0 | VS-Kanal 17 mit festen SDK-/CRT-Versionen: SDK 10.0.26100, CRT 14.44.17.14; statische CRT | +| macOS arm64 | cargo-zigbuild 0.23.0, Zig 0.16.0 | enthaltenes MacOSX11.3.sdk; Deployment Target 11.0 | +| Linux amd64/arm64 | cargo-zigbuild 0.23.0, Zig 0.16.0 | glibc 2.28 | + +Rust 1.97.1 ist in `rust-toolchain.toml` fixiert. Die Images stehen mit Digest +in `.gitea/workflows/build.yml`; SDK/Clang/Zig stammen aus diesen Images. +7-Zip 25.01 wird mit fester SHA-256 in `bootstrap.sh` bereitgestellt. +Zusätzlich prüft der Windows-Build einen festen Hash aller SDK-/CRT-Dateien +und Symlinks. Änderungen unter derselben Microsoft-Versionsbezeichnung +werden damit abgelehnt; der Pin muss dann ausdrücklich aktualisiert werden. +Die Tabelle nennt Buildvorgaben, keine gemessenen minimalen OS-Versionen. +Die tatsächliche Cross-Matrix und OS-Läufe sind im Changebericht auszuweisen. + +Der Builder erfordert Linux aarch64. Zwei Cargo-Buildjobs und eine sequenzielle +Zielmatrix begrenzen die Last. Host-`tb-template` prüft über denselben Parser +wie der Exportdienst PE32+/amd64/Console, Mach-O/arm64 oder ELF/Linux/64-Bit; +fremde Executables werden beim Paketieren nicht ausgeführt. + +Lokaler Aufruf innerhalb des betreffenden gepinnten Containers: + +```sh +sh .gitea/scripts/bootstrap.sh +python3 .gitea/scripts/build.py --target x86_64-pc-windows-msvc --output dist +``` + +Eigene native Testpakete lassen sich mit `distribution.py pack --bin-dir ... +--target ... --output ... --inspector .../tb-template` erstellen. Uncommittete +Quellen bleiben in `manifest.json` markiert und sind nicht freigabefähig. + +## Origin-Konfiguration und Rechte + +Actions sind am Repository aktiviert. Der gemeinsame Runner heißt +`gitea-arm64-01`. Sein Neustartfehler wurde separat gemeldet; der Aufbau der +Repository-Workflows ändert keine globale Docker-/AppArmor-Konfiguration. + +Erforderliche Konfiguration: + +- Variable `TB_VBDOS_REPOSITORY`: erreichbarer Git-Bestand des in + `foreign.rs` fixierten Referenzprojekts. Der Checkout muss exakt + `1cdd2b32b829fe1721d0b6aecc433abc47a96fb6` liefern. Fehlende Konfiguration + lässt den Pflichtjob scheitern; Fremdprogramme werden nicht übersprungen. +- Secret `TB_RELEASE_TOKEN`: Gitea-Zugang nur für dieses Repository und die + Releaseverwaltung. Nur der Tag-Entwurfsjob und der manuelle Freigabeworkflow + referenzieren es. Es wird weder im Checkout gespeichert noch geloggt. +- PRs aus fremden Repositories führen keinen unkontrollierten Code auf dem + gemeinsamen persönlichen Runner aus. Interne PRs/Pushes erhalten keine + Veröffentlichungsschritte. Die tatsächliche Gitea-/Runner-Kompatibilität + einschließlich Jobrechten muss der erste Origin-Lauf bestätigen. + +Die Actions-URLs sind explizite Gitea-URLs mit festen Commit-IDs. +[Absolute Action-URLs](https://docs.gitea.com/usage/actions/comparison/) +und [Runnerlabels](https://docs.gitea.com/runner/) entsprechen dem Gitea-Modell. + +## Pakete und Zielprüfungen + +`terminalbasic--windows-amd64.7z` sowie `...-macos-arm64.tar.gz`, +`...-linux-amd64.tar.gz`, `...-linux-arm64.tar.gz` enthalten `tb`/`tbc` im Hauptverzeichnis und +`runtimes//tbrt` samt `tbrt.meta` (Windows jeweils `.exe` +bzw. `tbrt.exe.meta`), +`LICENSE`, `INSTALL.txt` und `manifest.json`. Unix-Executables besitzen 0755. +Das Manifest bindet Version, Revision, Rust, Buildhost/Image, Target und +SHA-256 jeder Datei. Jedes Paket erhält zusätzlich eine `.sha256`-Datei. + +Auf dem passenden Prüfsystem das unveränderte Paket herunterladen und ausführen: + +```sh +python3 .gitea/scripts/distribution.py target-check \ + --archive /pakete/terminalbasic-0.1.0-macos-arm64.tar.gz \ + --target aarch64-apple-darwin --output /nachweise/aarch64-apple-darwin +``` + +Das Prüfsystem braucht Python und den Prüfharness dieser Revision; die +Produkte selbst laufen aus einem neu entpackten temporären Verzeichnis. +Native-/TBL-Prüfungen verwenden einen leeren PATH, separate Verbraucher, +keine Library-Quellen und die vorhandenen paketierten Metadaten. Auf macOS +bleibt `/usr/bin/codesign` als Systemhilfe zulässig. Erzeugte Executables +laufen nach Entfernen von Quellen, TBL/TBC und Vorlagen weiter. +Die gemeinsame `portable.tbl` wird auf allen Zielen unverändert verwendet, +SHA-256 `5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df`. + +Windows erfordert zusätzlich `--windows-console-test ` +derselben Revision. Dieses Testexecutable kann der Linux-Builder mit +`cargo xwin test --locked --target x86_64-pc-windows-msvc -p tb-ui +--features terminal --no-run` erzeugen; es gehört zum Prüfharness, nicht zum +Anwenderpaket. DOSBox kann diese Windows-PE-Programme nicht ausführen. +Windows bleibt auf Benutzerentscheidung vorerst offen. + +Der automatisch erzeugte `report.json` lässt die manuelle Terminalabnahme +offen. Die Bedienfolge steht in `docs/plattformmatrix.md`. Je Target sind +zusätzlich `manual.json` und die referenzierten nichtleeren Belegdateien nötig: + +```json +{ + "target": "aarch64-apple-darwin", + "revision": "<40-stellige Revision>", + "package_sha256": "", + "passed": true, + "tester": "", + "terminal_versions": {"terminal.app": ""}, + "cases": {"f1_f12": true, "modifiers": true, "mouse": true, + "unicode_colors": true, "resize": true, "input_break": true, "shell": true}, + "evidence": ["terminal-protokoll.txt"] +} +``` + +Windows verlangt `windows-terminal`, beide Linux-Ziele jeweils `xterm` und +`vte` mit Versionen. Nur tatsächlich bestandene Schritte auf true setzen. +Die Felder dienen einer verantworteten manuellen Bestätigung; sie ersetzen +keine Durchführung. Herkunft wird über den geprüften Origin-Commit gebunden. + +## Entwurf und Veröffentlichung + +Ein Push des passenden Tags `v` baut/testet alle vier Ziele und lädt +erst danach neun Assets in einen Gitea-Entwurf: vier Pakete, vier SHA-Dateien, +`acceptance.json`. Dessen Referenzlauf enthält Fremdprogramme, Inventar, +Workspace/Clippy/Format, Compile-/VM-Benchmarks und die ausdrücklich gestartete +native IDE-Abnahme. Golden-Erzeugung bleibt bewusst ignoriert. Echte native +Paket-/Terminalprüfungen sind eine zusätzliche Freigabebedingung. + +Nachweise auf separaten Systemen beziehen sich auf diese Originalpakete. +Unter `release-evidence/v//` werden `report.json`, Logs, +`manual.json` und dessen Belege in einem Origin-Commit bereitgestellt. +Der manuell auf main gestartete Workflow „Geprüften Gitea-Entwurf freigeben“ +erhält Tag und vollständige Nachweisrevision. Er lädt die ursprünglichen +Entwurfsassets, prüft vier exakte Paketbindungen, Ziel-/Terminalresultate, +gemeinsame TBL-Prüfsumme und die Grundabnahme aus dem ursprünglichen Taglauf. +Er baut die Pakete dabei nicht erneut. Fehlende oder abweichende Daten sperren +Freigabe. Der Tag muss zur Paketversion und zur geprüften Revision passen. + +Uploads werden zurückgelesen und bytegenau geprüft. Wiederholungen ergänzen +nur fehlende identische Assets eines Entwurfs. Abweichende Assets oder ein +bereits veröffentlichter Release werden nicht überschrieben. Erst der letzte +API-Aufruf ändert `draft` auf false. Die Regressionen simulieren insbesondere +fehlende Uploads, falsche Nachweise, korrupte Pakete und bestehende Releases; +sie erzeugen keine öffentlichen Testreleases. diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md b/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md index 9ed6dd3..8134698 100644 --- a/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md @@ -12,7 +12,7 @@ Origin ist `https://git.rfc1437.de/hugo/TerminalBasic.git`; die read-only Versio 1. `.gitea/workflows/` nutzt den vorhandenen Linux-arm64-Runner für alle vier Build-/Paketziele. Vorhandene Workflowmuster der anderen Origin-Projekte wiederverwenden: cargo-zigbuild für Linux amd64 und macOS arm64, cargo-xwin für Windows amd64/MSVC; Linux arm64 nativ oder mit derselben festgelegten Linux-Zielbaseline. Container/Tools und benötigte SDKs/Sysroots reproduzierbar pinnen; konkrete Rust-/OS-/glibc-Versionen mit TerminalBasic prüfen. Das Runnerlabel `linux-arm64` bei Anbindung bestätigen. Vier native Buildrunner sind nicht erforderlich. `build-runtime.py` erzeugt Vorlagenmetadaten mit dem Hostwerkzeug für das jeweilige Target; fremde Executables werden auf dem Buildhost nicht nativ ausgeführt. 2. Wiederverwendbare Repository-Skripte erledigen Build, Tests, Paketierung und Prüfung auch lokal. Source-Checkout vom Gitea-Origin, alle zusätzlichen Actions nur über explizite Gitea-URLs und feste Revisionen, soweit überhaupt nötig; keine implizite fremde Action-Auflösung. Rust und benötigte Systemwerkzeuge versioniert bereitstellen. Server-/Runner-Kompatibilität praktisch prüfen, statt lediglich YAML zu validieren. -3. Matrixprodukte: `terminalbasic--windows-amd64.7z`, `terminalbasic--macos-arm64.tar.gz`, `terminalbasic--linux-amd64.tar.gz`, `terminalbasic--linux-arm64.tar.gz`. Windows enthält `tb.exe`/`tbc.exe`/`tbrt.exe`, übrige `tb`/`tbc`/`tbrt`; tbrt ist die native Exportvorlage, dazu deren Metadaten, Lizenz, Kurzinstallation. Archive dürfen keine Buildverzeichnis-/Quellbaumabhängigkeiten haben. Exportierte Anwenderprogramme bleiben normale native Einzelartefakte; die Archivformate betreffen die Distribution. +3. Matrixprodukte: `terminalbasic--windows-amd64.7z`, `terminalbasic--macos-arm64.tar.gz`, `terminalbasic--linux-amd64.tar.gz`, `terminalbasic--linux-arm64.tar.gz`. Windows enthält `tb.exe`/`tbc.exe`/`tbrt.exe`, übrige `tb`/`tbc`/`tbrt`; tbrt ist die native Exportvorlage unter `runtimes//`, dazu deren Metadaten, Lizenz, Kurzinstallation. Das vorhandene CLI-/IDE-Suchschema bleibt erhalten. Archive dürfen keine Buildverzeichnis-/Quellbaumabhängigkeiten haben. Exportierte Anwenderprogramme bleiben normale native Einzelartefakte; die Archivformate betreffen die Distribution. 4. Der Linux-Buildhost erzeugt/prüft Windows-Archive mit 7-Zip und Unix-Archive mit tar+gzip unter Erhalt der Executable-Bits. Inhalts-/Formatprüfungen laufen dort; tatsächliche Start-/Exportprüfungen verwenden neu entpackte Pakete auf passenden Zielsystemen aus 05, automatisiert oder dokumentiert manuell. Externe Nachweise müssen an Revision und exakte Paketprüfsumme gebunden und vor Freigabe geprüft sein. Ein gemeinsames TBL-Testartefakt wird einmal erzeugt und mit nachgewiesen identischen Bytes auf allen vier Zielsystemen verwendet. Separate BASIC-Verbraucher werden mit den entpackten TB-Tools verknüpft, als TBC ausgeführt und mit tbrt als EXE exportiert. Library-Quellen sind dabei nicht verfügbar. Erzeugung/Linken werden in einer Umgebung ohne erreichbaren C-/Rust-Compiler oder nativen Linker geprüft; Systemhilfen zur EXE-Finalisierung dürfen verfügbar bleiben. Fertige EXEs laufen anschließend ohne externe TBL/TBC oder TB-Installation. 5. `cargo test --locked --workspace`, Clippy und Formatprüfung zentral auf dem Linux-arm64-Host; zielabhängige Rust-Testprogramme bei Bedarf cross-kompilieren und auf passenden Prüfsystemen ausführen. Native Tests aus 02/03/04 und automatisierbare Plattformtests aus 05 auf ihren tatsächlichen Zielen ausführen. Buildstatus und Ausführungsnachweise getrennt ausweisen; macOS-EXE-Finalisierung mit codesign erfolgt auf macOS. Den fixierten Fremdprogrammbestand ausdrücklich im erforderlichen Abnahmelauf bereitstellen. Compile-/VM-Messungen auf dokumentiertem Referenzrunner statt instabiler Debug-Zeitlimits in allen Jobs. 6. Gitea-Release erst nach allen Pflichtjobs, zugeordneten echten Zielnachweisen und Vollständigkeits-/Prüfsummenprüfung freigeben. Upload zunächst zu einem als Entwurf erkennbaren Release oder gleichwertigem nicht freigegebenen Staging; anschließend atomare Freigabe im Rahmen der verfügbaren API. PR-Jobs ohne Veröffentlichungsrechte und ohne Release-Secrets; fremder PR-Code darf nicht mit solchen Rechten auf persönlichen Runnern laufen. Zugangswerte werden als Gitea-Secrets konfiguriert, nicht committed. Tests erzeugen keine öffentlichen Testreleases. @@ -28,3 +28,20 @@ Origin ist `https://git.rfc1437.de/hugo/TerminalBasic.git`; die read-only Versio ## Migration Plan Lokale Skripte zuerst lauffähig machen, dann Gitea-Runner und Workflows anbinden. PR-/Push-Lauf ohne Veröffentlichung prüfen; kontrollierter Tag-/Release-Lauf nach erfolgreicher Matrix. Bisherige lokale Cargo-Nutzung erhalten. Rollback über vorheriges vollständiges Release und Rücknahme der Workflowänderung; keine Server-/Runnerinstallation durch bloße Proposal-Erstellung. + +## Konkretisierung während der Umsetzung + +- Rust 1.97.1, vorhandene Cross-Images per Digest, 7-Zip 25.01 per SHA-256. + SDK-/CRT-Versionen und ein Hash ihrer exakten Header-/Library-Bytes sind + für Windows fixiert; macOS-SDK/Zig stammen aus dem gepinnten Image. +- `tb-template --inspect` nutzt den vorhandenen PE/ELF/Mach-O-Parser auch + für tb/tbc. Build und Paketprüfung laufen auf dem Host ohne fremde Programme + auszuführen. Die Anwenderpakete benötigen tb-template nicht. +- Taglauf erzeugt erst nach Build/Grundabnahme einen überprüften Entwurf. + Originalpakete werden auf separaten Systemen geprüft. Ein manueller Workflow + auf main bindet deren Nachweise aus einem Origin-Commit an Tag, Revision und + Paket-SHA-256 und gibt erst dann denselben Entwurf frei; kein erneuter Bau. +- Die Benutzerentscheidung aus 05, Windows-Ausführung vorerst offen zu lassen, + bleibt erhalten. Sie macht Windows-Builds zulässig, aber keinen Release mit + fehlender Windows-Abnahme erfolgreich. Fehlende Nachweise werden nicht auf + Basis der gemeinsamen ANSI-Technik von macOS/Linux pauschal abgehakt. diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/clippy.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/clippy.log new file mode 100644 index 0000000..52e0ee5 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/clippy.log @@ -0,0 +1,6 @@ + Checking tb-frontend v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-frontend) + Checking tb-runtime v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-runtime) + Checking tb-ui v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-ui) + Checking tb-vm v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-vm) + Checking tb-export v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-export) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.74s diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/ide-pty.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/ide-pty.log new file mode 100644 index 0000000..7449283 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/ide-pty.log @@ -0,0 +1,3 @@ +PASS {'shell_exit': 7} +PASS {'abort': True} +PASS {'file_shell': True} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/library.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/library.log new file mode 100644 index 0000000..b8f37cd --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/library.log @@ -0,0 +1 @@ +{"target": "aarch64-apple-darwin", "tbl_sha256": "5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df", "native_execution": true, "source_free": true, "run_reset": true, "output": " 1 \n 7 3 9 1 \nTB \n"} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/native.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/native.log new file mode 100644 index 0000000..fe1753c --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/native.log @@ -0,0 +1,13 @@ +PASS native console +PASS native restart +PASS native stop +PASS native error +PASS native project +PASS native form +PASS native external +PASS PTY Eingabe, Abbruch und Wiederherstellung (CLI/native) +PASS Exportabbruch SIGINT/SIGTERM, Original und Bereinigung +PASS corrupted length +PASS corrupted version +PASS corrupted truncated +Native Abnahme bestanden: aarch64-apple-darwin diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/report.json b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/report.json new file mode 100644 index 0000000..154d6d4 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-macos-proof/report.json @@ -0,0 +1,16 @@ +{ + "target": "aarch64-apple-darwin", + "revision": "796564795a6607651c366c6b0de74560af55e71a", + "package": "terminalbasic-0.1.0-macos-arm64.tar.gz", + "package_sha256": "369882d9962f0264f41a7dfc0e352acb826c43d84a3c8babd028636a24aeaf4d", + "tbl_sha256": "5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df", + "host": "macOS-26.6.2-arm64-arm-64bit-Mach-O", + "automated_passed": true, + "manual_terminal_passed": false, + "checks": { + "default-template": "passed", + "native": "passed", + "library": "passed", + "ide-pty": "passed" + } +} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-unix-build.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-unix-build.log new file mode 100644 index 0000000..16ddc81 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-unix-build.log @@ -0,0 +1,270 @@ +info: syncing channel updates for '1.97.1-aarch64-unknown-linux-gnu' +info: latest update on 2026-07-16, rust version 1.97.1 (8bab26f4f 2026-07-14) +info: downloading component 'cargo' +info: downloading component 'clippy' +info: downloading component 'rust-std' +info: downloading component 'rustc' +info: downloading component 'rustfmt' +info: installing component 'cargo' +info: installing component 'clippy' +info: installing component 'rust-std' +info: installing component 'rustc' +info: installing component 'rustfmt' + + 1.97.1-aarch64-unknown-linux-gnu installed - rustc 1.97.1 (8bab26f4f 2026-07-14) + +info: default toolchain set to '1.97.1-aarch64-unknown-linux-gnu' +info: checking for self-update +info: downloading self-update +/tmp/tb-7zip.tar.xz: OK +rustc 1.97.1 (8bab26f4f 2026-07-14) + +7-Zip (z) 25.01 (arm64) : Copyright (c) 1999-2025 Igor Pavlov : 2025-08-03 + 64-bit arm_v:8-A locale=C.UTF-8 Threads:4 OPEN_MAX:1024, ASM + ++ rustup target add aarch64-unknown-linux-gnu +info: component rust-std is up to date ++ cargo zigbuild --locked --release --target aarch64-unknown-linux-gnu.2.28 -p tb-ide -p tb-cli -p tb-runner --bins + Updating crates.io index + Downloading crates ... + Downloaded bitflags v1.3.2 + Downloaded cassowary v0.3.0 + Downloaded anyhow v1.0.104 + Downloaded bitflags v2.13.1 + Downloaded equivalent v1.0.2 + Downloaded allocator-api2 v0.2.21 + Downloaded cfg-if v1.0.4 + Downloaded darling_core v0.24.1 + Downloaded indoc v2.0.7 + Downloaded scopeguard v1.2.0 + Downloaded defmt v1.1.1 + Downloaded either v1.18.0 + Downloaded signal-hook-mio v0.2.5 + Downloaded compact_str v0.8.2 + Downloaded static_assertions v1.1.0 + Downloaded strsim v0.11.1 + Downloaded unicode-ident v1.0.24 + Downloaded jiff-core v0.1.0 + Downloaded syn v2.0.119 + Downloaded defmt-macros v1.1.1 + Downloaded defmt-parser v1.0.0 + Downloaded foldhash v0.1.5 + Downloaded parking_lot v0.12.5 + Downloaded rustix v0.38.44 + Downloaded darling_macro v0.24.1 + Downloaded thiserror v2.0.20 + Downloaded unicase v2.9.0 + Downloaded itoa v1.0.18 + Downloaded paste v1.0.15 + Downloaded serde_core v1.0.229 + Downloaded quote v1.0.47 + Downloaded mio v1.2.2 + Downloaded ryu v1.0.23 + Downloaded strum_macros v0.26.4 + Downloaded jiff-static v0.2.35 + Downloaded unicode-width v0.1.14 + Downloaded log v0.4.34 + Downloaded signal-hook v0.3.18 + Downloaded crossterm v0.28.1 + Downloaded hashbrown v0.15.5 + Downloaded strum v0.26.3 + Downloaded itertools v0.13.0 + Downloaded heck v0.5.0 + Downloaded redb v4.2.0 + Downloaded syn v3.0.4 + Downloaded jiff v0.2.35 + Downloaded castaway v0.2.4 + Downloaded rustversion v1.0.23 + Downloaded instability v0.3.13 + Downloaded errno v0.3.14 + Downloaded lru v0.12.5 + Downloaded smallvec v1.15.2 + Downloaded parking_lot_core v0.9.12 + Downloaded proc-macro2 v1.0.107 + Downloaded ident_case v1.0.1 + Downloaded thiserror-impl v2.0.20 + Downloaded unicode-segmentation v1.13.3 + Downloaded unicode-truncate v1.1.0 + Downloaded darling v0.24.1 + Downloaded pulldown-cmark v0.13.4 + Downloaded unicode-width v0.2.0 + Downloaded memchr v2.8.3 + Downloaded linux-raw-sys v0.4.15 + Downloaded signal-hook-registry v1.4.8 + Downloaded ratatui v0.29.0 + Downloaded libc v0.2.189 + Downloaded lock_api v0.4.14 +warning: linker stderr: ignoring deprecated linker optimization setting '1' + | + = note: `#[warn(linker_messages)]` on by default + +warning: `tb-cli` (bin "tbc") generated 1 warning +warning: `tb-runner` (bin "tbrt") generated 1 warning (1 duplicate) +warning: `tb-ide` (bin "tb") generated 1 warning (1 duplicate) + Finished `release` profile [optimized] target(s) in 1.55s ++ cargo build --locked --release -p tb-export --bin tb-template + Finished `release` profile [optimized] target(s) in 0.04s ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tb aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tbc aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tbrt aarch64-unknown-linux-gnu ++ /work/target/release/tb-template /tmp/tb-pack-3ccs00ug/tbrt aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-27ro6ib_/tb aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-27ro6ib_/tbc aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-27ro6ib_/tbrt aarch64-unknown-linux-gnu +/work/dist/terminalbasic-0.1.0-linux-arm64.tar.gz ++ /tmp/tb-unpacked-c072ix0x/tb --help ++ /usr/bin/python3 /work/tests/support/native-abnahme.py --bin-dir /tmp/tb-unpacked-c072ix0x --target aarch64-unknown-linux-gnu ++ /usr/bin/python3 /work/tests/support/library-abnahme.py --bin-dir /tmp/tb-unpacked-c072ix0x ++ /usr/bin/python3 /work/tests/support/ide-execution-pty.py --binary /tmp/tb-unpacked-c072ix0x/tb ++ rustup target add x86_64-unknown-linux-gnu +info: downloading component rust-std ++ cargo zigbuild --locked --release --target x86_64-unknown-linux-gnu.2.28 -p tb-ide -p tb-cli -p tb-runner --bins + Compiling libc v0.2.189 + Compiling syn v3.0.4 + Compiling rustversion v1.0.23 + Compiling log v0.4.34 + Compiling errno v0.3.14 + Compiling ident_case v1.0.1 + Compiling signal-hook v0.3.18 + Compiling cfg-if v1.0.4 + Compiling strsim v0.11.1 + Compiling parking_lot_core v0.9.12 + Compiling darling_core v0.24.1 + Compiling signal-hook-registry v1.4.8 + Compiling scopeguard v1.2.0 + Compiling smallvec v1.15.2 + Compiling bitflags v2.13.1 + Compiling rustix v0.38.44 + Compiling thiserror v2.0.20 + Compiling lock_api v0.4.14 + Compiling darling_macro v0.24.1 + Compiling thiserror-impl v2.0.20 + Compiling mio v1.2.2 + Compiling syn v2.0.119 + Compiling allocator-api2 v0.2.21 + Compiling either v1.18.0 + Compiling instability v0.3.13 + Compiling equivalent v1.0.2 + Compiling paste v1.0.15 + Compiling foldhash v0.1.5 + Compiling heck v0.5.0 + Compiling linux-raw-sys v0.4.15 + Compiling strum_macros v0.26.4 + Compiling hashbrown v0.15.5 + Compiling itertools v0.13.0 + Compiling redb v4.2.0 + Compiling signal-hook-mio v0.2.5 + Compiling darling v0.24.1 + Compiling parking_lot v0.12.5 + Compiling castaway v0.2.4 + Compiling itoa v1.0.18 + Compiling ryu v1.0.23 + Compiling unicode-width v0.2.0 + Compiling static_assertions v1.1.0 + Compiling unicode-segmentation v1.13.3 + Compiling indoc v2.0.7 + Compiling jiff-core v0.1.0 + Compiling unicode-width v0.1.14 + Compiling unicode-truncate v1.1.0 + Compiling jiff v0.2.35 + Compiling compact_str v0.8.2 + Compiling crossterm v0.28.1 + Compiling strum v0.26.3 + Compiling lru v0.12.5 + Compiling cassowary v0.3.0 + Compiling ratatui v0.29.0 + Compiling tb-runtime v0.1.0 (/work/crates/tb-runtime) + Compiling tb-frontend v0.1.0 (/work/crates/tb-frontend) + Compiling anyhow v1.0.104 + Compiling tb-ui v0.1.0 (/work/crates/tb-ui) + Compiling tb-vm v0.1.0 (/work/crates/tb-vm) + Compiling tb-export v0.1.0 (/work/crates/tb-export) + Compiling pulldown-cmark v0.13.4 + Compiling memchr v2.8.3 + Compiling unicase v2.9.0 + Compiling tb-runner v0.1.0 (/work/crates/tb-runner) + Compiling tb-ide v0.1.0 (/work/crates/tb-ide) +warning: linker stderr: ignoring deprecated linker optimization setting '1' + | + = note: `#[warn(linker_messages)]` on by default + +warning: `tb-runner` (bin "tbrt") generated 1 warning + Compiling tb-cli v0.1.0 (/work/crates/tb-cli) +warning: `tb-ide` (bin "tb") generated 1 warning (1 duplicate) +warning: `tb-cli` (bin "tbc") generated 1 warning (1 duplicate) + Finished `release` profile [optimized] target(s) in 2m 23s ++ cargo build --locked --release -p tb-export --bin tb-template + Finished `release` profile [optimized] target(s) in 0.06s ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tb x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tbc x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tbrt x86_64-unknown-linux-gnu ++ /work/target/release/tb-template /tmp/tb-pack-3e1u_9my/tbrt x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-lwy0qi08/tb x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-lwy0qi08/tbc x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-lwy0qi08/tbrt x86_64-unknown-linux-gnu +/work/dist/terminalbasic-0.1.0-linux-amd64.tar.gz ++ rustup target add aarch64-apple-darwin +info: downloading component rust-std ++ cargo zigbuild --locked --release --target aarch64-apple-darwin -p tb-ide -p tb-cli -p tb-runner --bins + Compiling libc v0.2.189 + Compiling log v0.4.34 + Compiling cfg-if v1.0.4 + Compiling signal-hook v0.3.18 + Compiling parking_lot_core v0.9.12 + Compiling smallvec v1.15.2 + Compiling bitflags v2.13.1 + Compiling scopeguard v1.2.0 + Compiling lock_api v0.4.14 + Compiling rustix v0.38.44 + Compiling thiserror v2.0.20 + Compiling equivalent v1.0.2 + Compiling allocator-api2 v0.2.21 + Compiling errno v0.3.14 + Compiling signal-hook-registry v1.4.8 + Compiling mio v1.2.2 + Compiling foldhash v0.1.5 + Compiling either v1.18.0 + Compiling itertools v0.13.0 + Compiling signal-hook-mio v0.2.5 + Compiling hashbrown v0.15.5 + Compiling redb v4.2.0 + Compiling parking_lot v0.12.5 + Compiling castaway v0.2.4 + Compiling ryu v1.0.23 + Compiling static_assertions v1.1.0 + Compiling unicode-width v0.2.0 + Compiling unicode-segmentation v1.13.3 + Compiling unicode-width v0.1.14 + Compiling itoa v1.0.18 + Compiling jiff-core v0.1.0 + Compiling unicode-truncate v1.1.0 + Compiling compact_str v0.8.2 + Compiling jiff v0.2.35 + Compiling crossterm v0.28.1 + Compiling strum v0.26.3 + Compiling lru v0.12.5 + Compiling cassowary v0.3.0 + Compiling ratatui v0.29.0 + Compiling tb-runtime v0.1.0 (/work/crates/tb-runtime) + Compiling tb-frontend v0.1.0 (/work/crates/tb-frontend) + Compiling anyhow v1.0.104 + Compiling tb-ui v0.1.0 (/work/crates/tb-ui) + Compiling tb-vm v0.1.0 (/work/crates/tb-vm) + Compiling tb-export v0.1.0 (/work/crates/tb-export) + Compiling pulldown-cmark v0.13.4 + Compiling unicase v2.9.0 + Compiling memchr v2.8.3 + Compiling tb-runner v0.1.0 (/work/crates/tb-runner) + Compiling tb-ide v0.1.0 (/work/crates/tb-ide) + Compiling tb-cli v0.1.0 (/work/crates/tb-cli) + Finished `release` profile [optimized] target(s) in 2m 16s ++ cargo build --locked --release -p tb-export --bin tb-template + Finished `release` profile [optimized] target(s) in 0.06s ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tb aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tbc aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tbrt aarch64-apple-darwin ++ /work/target/release/tb-template /tmp/tb-pack-ymsier7a/tbrt aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-e391lcwl/tb aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-e391lcwl/tbc aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-e391lcwl/tbrt aarch64-apple-darwin +/work/dist/terminalbasic-0.1.0-macos-arm64.tar.gz diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-windows-build.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-windows-build.log new file mode 100644 index 0000000..2e8424d --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/cross-windows-build.log @@ -0,0 +1,279 @@ +info: syncing channel updates for '1.97.1-aarch64-unknown-linux-gnu' +info: latest update on 2026-07-16, rust version 1.97.1 (8bab26f4f 2026-07-14) +info: component 'clippy' for target 'aarch64-unknown-linux-gnu' is up to date +info: component 'rustfmt' for target 'aarch64-unknown-linux-gnu' is up to date + + 1.97.1-aarch64-unknown-linux-gnu unchanged - rustc 1.97.1 (8bab26f4f 2026-07-14) + +info: checking for self-update +info: downloading self-update +/tmp/tb-7zip.tar.xz: OK +rustc 1.97.1 (8bab26f4f 2026-07-14) + +7-Zip (z) 25.01 (arm64) : Copyright (c) 1999-2025 Igor Pavlov : 2025-08-03 + 64-bit arm_v:8-A locale=C.UTF-8 Threads:4 OPEN_MAX:1024, ASM + ++ rustup target add x86_64-pc-windows-msvc +info: component rust-std for target x86_64-pc-windows-msvc is up to date ++ cargo xwin build --locked --release --target x86_64-pc-windows-msvc -p tb-ide -p tb-cli -p tb-runner --bins + Updating crates.io index + Downloading crates ... + Downloaded indoc v2.0.7 + Downloaded bitflags v2.13.1 + Downloaded heck v0.5.0 + Downloaded paste v1.0.15 + Downloaded bitflags v1.3.2 + Downloaded strum_macros v0.26.4 + Downloaded anyhow v1.0.104 + Downloaded syn v3.0.4 + Downloaded allocator-api2 v0.2.21 + Downloaded cassowary v0.3.0 + Downloaded windows-sys v0.59.0 + Downloaded unicode-segmentation v1.13.3 + Downloaded defmt-parser v1.0.0 + Downloaded parking_lot v0.12.5 + Downloaded thiserror v2.0.20 + Downloaded thiserror-impl v2.0.20 + Downloaded castaway v0.2.4 + Downloaded jiff-tzdb v0.1.8 + Downloaded static_assertions v1.1.0 + Downloaded windows-link v0.2.1 + Downloaded darling_macro v0.24.1 + Downloaded errno v0.3.14 + Downloaded defmt-macros v1.1.1 + Downloaded jiff-static v0.2.35 + Downloaded cfg-if v1.0.4 + Downloaded log v0.4.34 + Downloaded lru v0.12.5 + Downloaded serde_core v1.0.229 + Downloaded rustversion v1.0.23 + Downloaded unicode-truncate v1.1.0 + Downloaded signal-hook v0.3.18 + Downloaded signal-hook-mio v0.2.5 + Downloaded unicase v2.9.0 + Downloaded scopeguard v1.2.0 + Downloaded windows-targets v0.52.6 + Downloaded defmt v1.1.1 + Downloaded ident_case v1.0.1 + Downloaded jiff-tzdb-platform v0.1.3 + Downloaded quote v1.0.47 + Downloaded strsim v0.11.1 + Downloaded strum v0.26.3 + Downloaded itoa v1.0.18 + Downloaded equivalent v1.0.2 + Downloaded instability v0.3.13 + Downloaded foldhash v0.1.5 + Downloaded smallvec v1.15.2 + Downloaded crossterm_winapi v0.9.1 + Downloaded signal-hook-registry v1.4.8 + Downloaded either v1.18.0 + Downloaded parking_lot_core v0.9.12 + Downloaded ryu v1.0.23 + Downloaded compact_str v0.8.2 + Downloaded darling_core v0.24.1 + Downloaded lock_api v0.4.14 + Downloaded proc-macro2 v1.0.107 + Downloaded unicode-ident v1.0.24 + Downloaded darling v0.24.1 + Downloaded memchr v2.8.3 + Downloaded mio v1.2.2 + Downloaded crossterm v0.28.1 + Downloaded jiff-core v0.1.0 + Downloaded itertools v0.13.0 + Downloaded hashbrown v0.15.5 + Downloaded pulldown-cmark v0.13.4 + Downloaded unicode-width v0.2.0 + Downloaded redb v4.2.0 + Downloaded unicode-width v0.1.14 + Downloaded rustix v0.38.44 + Downloaded syn v2.0.119 + Downloaded ratatui v0.29.0 + Downloaded jiff v0.2.35 + Downloaded libc v0.2.189 + Downloaded windows_x86_64_msvc v0.52.6 + Downloaded winapi v0.3.9 + Downloaded linux-raw-sys v0.4.15 + Downloaded windows-sys v0.61.2 +warning: linker stderr: lld-link: Cannot use debug info for 'libcmt.lib(std_type_info_static.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(fltused.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(tlssup.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(delete_scalar_size.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(gs_cookie.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(guard_support.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(delete_scalar.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(initializers.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(utility_desktop.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(gshandler.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(gs_report.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(throw.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(riscchandler.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(risctrnsctrl.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(ehhelpers.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(cpu_disp.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(pesect.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(jbcxrval.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(per_thread_data.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(ehstate.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(frame.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(wcschr.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(winapi_downlevel.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(std_exception.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(std_type_info.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(gshandlerseh.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(undname.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(purevirt.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(locks.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(purevirt_data.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(strrchr.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(jmpuwind.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(exe_main.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(loadcfg.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(utility.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(gs_support.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(matherr.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(argv_mode.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(commit_mode.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(file_mode.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(new_mode.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(thread_locale.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(tncleanup.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(env_mode.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(invalid_parameter_handler.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(denormal_control.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(default_local_stdio_options.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(matherr_detection.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(dyn_tls_init.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(dyn_tls_dtor.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(initsect.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(softmemtag.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(initialization.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libcmt.lib(ucrt_detection.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory + + lld-link: Cannot use debug info for 'libvcruntime.lib(strchr.obj)' [LNK4099] + >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory + | + = note: `#[warn(linker_messages)]` on by default + +warning: `tb-runner` (bin "tbrt") generated 1 warning +warning: `tb-ide` (bin "tb") generated 1 warning (1 duplicate) +warning: `tb-cli` (bin "tbc") generated 1 warning (1 duplicate) + Finished `release` profile [optimized] target(s) in 1.75s ++ cargo build --locked --release -p tb-export --bin tb-template + Finished `release` profile [optimized] target(s) in 0.04s ++ /work/target/release/tb-template --inspect /work/target/x86_64-pc-windows-msvc/release/tb.exe x86_64-pc-windows-msvc ++ /work/target/release/tb-template --inspect /work/target/x86_64-pc-windows-msvc/release/tbc.exe x86_64-pc-windows-msvc ++ /work/target/release/tb-template --inspect /work/target/x86_64-pc-windows-msvc/release/tbrt.exe x86_64-pc-windows-msvc ++ /work/target/release/tb-template /tmp/tb-pack-am6i0jvn/runtimes/x86_64-pc-windows-msvc/tbrt.exe x86_64-pc-windows-msvc ++ /usr/local/bin/7zz a -t7z /work/dist-pinned/terminalbasic-0.1.0-windows-amd64.7z INSTALL.txt LICENSE manifest.json runtimes/x86_64-pc-windows-msvc/tbrt.exe runtimes/x86_64-pc-windows-msvc/tbrt.exe.meta tb.exe tbc.exe ++ /usr/local/bin/7zz x -y -o/tmp/tb-package-5j84dd93 -- /work/dist-pinned/terminalbasic-0.1.0-windows-amd64.7z ++ /work/target/release/tb-template --inspect /tmp/tb-package-5j84dd93/tb.exe x86_64-pc-windows-msvc ++ /work/target/release/tb-template --inspect /tmp/tb-package-5j84dd93/tbc.exe x86_64-pc-windows-msvc ++ /work/target/release/tb-template --inspect /tmp/tb-package-5j84dd93/runtimes/x86_64-pc-windows-msvc/tbrt.exe x86_64-pc-windows-msvc +/work/dist-pinned/terminalbasic-0.1.0-windows-amd64.7z diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/export-tests.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/export-tests.log new file mode 100644 index 0000000..852678a --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/export-tests.log @@ -0,0 +1,24 @@ + Compiling tb-vm v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-vm) + Compiling tb-export v0.1.0 (/Users/gb/Projects/TerminalBasic/crates/tb-export) + Finished `test` profile [unoptimized + debuginfo] target(s) in 3.69s + Running unittests src/lib.rs (target/debug/deps/tb_export-25aa117d19f46d7a) + +running 3 tests +test tests::publication_preserves_originals_on_conflict_failure_race_and_cancel ... ok +test tests::fehlgeschlagene_native_finalisierung_erhaelt_das_ziel ... ok +test tests::targets_versions_integrity_and_payload_bounds_are_enforced ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s + + Running unittests src/bin/tb-template.rs (target/debug/deps/tb_template-ef8c38310b67cef7) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_export + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/implementation-sha256.json b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/implementation-sha256.json new file mode 100644 index 0000000..33bfdf7 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/implementation-sha256.json @@ -0,0 +1,12 @@ +{ + ".gitea/INSTALL.txt": "8dedd68d8c03e56a6f322bad6451a0403eca3abf2fffb3260dd07a8c6a5ba98f", + ".gitea/scripts/acceptance.py": "89d84d678095be7cd3ffb8bd8ea40cb2312f77f4776ecec4544bcc1cbc24b51a", + ".gitea/scripts/bootstrap.sh": "ac6d7d605fcb314c2a267fbe549ce54a5bce562d4c4a173f5e1f25eeeebba2a3", + ".gitea/scripts/build.py": "71f00d0fc41b998a168e7599b6c619ebfcc80f61695ff25d5c5233ee98111644", + ".gitea/scripts/distribution.py": "de9b1ec3cd189102952372937daa72e0566cb342286b7c3b2f8fd8a72ccb28f6", + ".gitea/scripts/publish.py": "e5598cd5399dca58c01a118d2ecf044126f0de5226be05d1e64edbc51c955804", + ".gitea/scripts/release.py": "fe0e3fc55e22de10bfc244623f0df3395cececc474834a844fe850bc70468c93", + ".gitea/scripts/test_distribution.py": "f09463bb8528dedc5df7dd98f85c4d04e2231a5821f528a6e32400231f4f5c4b", + ".gitea/workflows/build.yml": "60842092d3ce09dcf7e303a1186dfdd3f409a47c314c18bcde90eb644930322f", + ".gitea/workflows/publish.yml": "30dff7b2045b80d5961407bc501334c3c9fa154133fa3d8eb925e5e87d0d3592" +} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/ide-pty.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/ide-pty.log new file mode 100644 index 0000000..7449283 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/ide-pty.log @@ -0,0 +1,3 @@ +PASS {'shell_exit': 7} +PASS {'abort': True} +PASS {'file_shell': True} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/library.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/library.log new file mode 100644 index 0000000..4a48b4c --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/library.log @@ -0,0 +1 @@ +{"target": "aarch64-unknown-linux-gnu", "tbl_sha256": "5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df", "native_execution": true, "source_free": true, "run_reset": true, "output": " 1 \n 7 3 9 1 \nTB \n"} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/native.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/native.log new file mode 100644 index 0000000..d6b4e02 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/native.log @@ -0,0 +1,13 @@ +PASS native console +PASS native restart +PASS native stop +PASS native error +PASS native project +PASS native form +PASS native external +PASS PTY Eingabe, Abbruch und Wiederherstellung (CLI/native) +PASS Exportabbruch SIGINT/SIGTERM, Original und Bereinigung +PASS corrupted length +PASS corrupted version +PASS corrupted truncated +Native Abnahme bestanden: aarch64-unknown-linux-gnu diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/report.json b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/report.json new file mode 100644 index 0000000..deb5132 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/linux-arm64-proof-final/report.json @@ -0,0 +1,16 @@ +{ + "target": "aarch64-unknown-linux-gnu", + "revision": "796564795a6607651c366c6b0de74560af55e71a", + "package": "terminalbasic-0.1.0-linux-arm64.tar.gz", + "package_sha256": "e1eff42146202fe4694b8812a17acfc9337a454a27c0ef36d53a3fc776088b81", + "tbl_sha256": "5d25c2f8c95ae535e55a6c84c1ddd0d964358863f4f3c780c50ac4a2eb3594df", + "host": "Linux-6.8.0-139-generic-aarch64-with-glibc2.41", + "automated_passed": true, + "manual_terminal_passed": false, + "checks": { + "default-template": "passed", + "native": "passed", + "library": "passed", + "ide-pty": "passed" + } +} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.json b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.json new file mode 100644 index 0000000..77d458e --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.json @@ -0,0 +1,12 @@ +{ + "revision": "796564795a6607651c366c6b0de74560af55e71a", + "passed": true, + "buildhost": "macOS-26.6.2-arm64-arm-64bit-Mach-O", + "run_url": "local-verification", + "foreign": true, + "inventory": true, + "workspace": true, + "benchmarks": true, + "native_ide": true, + "log_sha256": "f3b51d1f0155b0d8f33435f23206073d2dd19c7bad56c23ac7e4c32abe50af30" +} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.log new file mode 100644 index 0000000..1dc4602 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/acceptance.log @@ -0,0 +1,1005 @@ ++ cargo test --locked -p tb-cli --test foreign -- --include-ignored --nocapture + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.09s + Running tests/foreign.rs (target/debug/deps/foreign-92ee6191b667aed6) + +running 3 tests +test fehlender_oder_falscher_fremdbestand_wird_benannt ... ok +graphics/graphics.mak: Lauf 1 kompilieren +test prozessfrist::frist_beendet_blockierten_testprozess ... ok +graphics/graphics.mak: Start und initiale Ereignisse +graphics/graphics.mak: Taste "x", Modifikatoren 4 +graphics/graphics.mak: Lauf 1 bestanden +graphics/graphics.mak: Lauf 2 kompilieren +graphics/graphics.mak: Start und initiale Ereignisse +graphics/graphics.mak: Taste "x", Modifikatoren 4 +graphics/graphics.mak: Lauf 2 bestanden +microsoft/check.mak: Lauf 1 kompilieren +microsoft/check.mak: Start und initiale Ereignisse +microsoft/check.mak: Taste "f", Modifikatoren 4 +microsoft/check.mak: Taste "x", Modifikatoren 0 +microsoft/check.mak: Lauf 1 bestanden +microsoft/check.mak: Lauf 2 kompilieren +microsoft/check.mak: Start und initiale Ereignisse +microsoft/check.mak: Taste "f", Modifikatoren 4 +microsoft/check.mak: Taste "x", Modifikatoren 0 +microsoft/check.mak: Lauf 2 bestanden +microsoft/qlbview.mak: Lauf 1 kompilieren +microsoft/qlbview.mak: Start und initiale Ereignisse +microsoft/qlbview.mak: Taste "\u{1b}", Modifikatoren 0 +microsoft/qlbview.mak: Lauf 1 bestanden +microsoft/qlbview.mak: Lauf 2 kompilieren +microsoft/qlbview.mak: Start und initiale Ereignisse +microsoft/qlbview.mak: Taste "\u{1b}", Modifikatoren 0 +microsoft/qlbview.mak: Lauf 2 bestanden +microsoft/seek.mak: Lauf 1 kompilieren +microsoft/seek.mak: Start und initiale Ereignisse +microsoft/seek.mak: Taste "x", Modifikatoren 4 +microsoft/seek.mak: Lauf 1 bestanden +microsoft/seek.mak: Lauf 2 kompilieren +microsoft/seek.mak: Start und initiale Ereignisse +microsoft/seek.mak: Taste "x", Modifikatoren 4 +microsoft/seek.mak: Lauf 2 bestanden +microsoft/spindemo.mak: Lauf 1 kompilieren +microsoft/spindemo.mak: Start und initiale Ereignisse +microsoft/spindemo.mak: Taste "\t", Modifikatoren 0 +microsoft/spindemo.mak: Taste "\t", Modifikatoren 0 +microsoft/spindemo.mak: Taste "\0H", Modifikatoren 0 +microsoft/spindemo.mak: Lauf 1 bestanden +microsoft/spindemo.mak: Lauf 2 kompilieren +microsoft/spindemo.mak: Start und initiale Ereignisse +microsoft/spindemo.mak: Taste "\t", Modifikatoren 0 +microsoft/spindemo.mak: Taste "\t", Modifikatoren 0 +microsoft/spindemo.mak: Taste "\0H", Modifikatoren 0 +microsoft/spindemo.mak: Lauf 2 bestanden +microsoft/notepad.frm: Lauf 1 kompilieren +microsoft/notepad.frm: Start und initiale Ereignisse +microsoft/notepad.frm: Taste "f", Modifikatoren 4 +microsoft/notepad.frm: Taste "x", Modifikatoren 0 +microsoft/notepad.frm: Lauf 1 bestanden +microsoft/notepad.frm: Lauf 2 kompilieren +microsoft/notepad.frm: Start und initiale Ereignisse +microsoft/notepad.frm: Taste "f", Modifikatoren 4 +microsoft/notepad.frm: Taste "x", Modifikatoren 0 +microsoft/notepad.frm: Lauf 2 bestanden +misc/mentors/mentors.frm: Lauf 1 kompilieren +misc/mentors/mentors.frm: Start und initiale Ereignisse +misc/mentors/mentors.frm: Taste "f", Modifikatoren 4 +misc/mentors/mentors.frm: Taste "x", Modifikatoren 0 +misc/mentors/mentors.frm: Lauf 1 bestanden +misc/mentors/mentors.frm: Lauf 2 kompilieren +misc/mentors/mentors.frm: Start und initiale Ereignisse +misc/mentors/mentors.frm: Taste "f", Modifikatoren 4 +misc/mentors/mentors.frm: Taste "x", Modifikatoren 0 +misc/mentors/mentors.frm: Lauf 2 bestanden +test oeffentliche_formularprogramme_sind_reproduzierbar_bedienbar ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.70s + ++ cargo test --locked --workspace + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.04s + Running unittests src/main.rs (target/debug/deps/tbc-a3652d07eb423d84) + +running 7 tests +test ide_acceptance::real_native_ide_exports_and_source_free_cli_library_consumer ... ignored, Echter Zielnachweis: TB_IDE_RUNTIME_DIR muss geprüfte Host-tbrt-Vorlage enthalten +test ide_acceptance::reference_matrix_is_complete_and_points_to_runnable_tests ... ok +test ide_acceptance::function_keys_conflict_contexts_and_errors_keep_a_single_input_owner ... ok +test ide_acceptance::partial_save_and_external_edit_recover_without_losing_documents ... ok +test ide_acceptance::saved_project_ide_source_cli_and_tbc_have_identical_sessions ... ok +test ide_acceptance::create_save_debug_help_exports_and_reopen ... ok +test ide_acceptance::every_menu_command_has_native_keyboard_and_mouse_routing ... ok + +test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.73s + + Running tests/compat.rs (target/debug/deps/compat-f89983ce5e40f582) + +running 18 tests +test erzeuge_sollausgaben ... ignored, erzeugt Golden Files; nur bewusst aufrufen +test uhr_direktive_wird_gelesen ... ok +test textabweichung_nennt_zeile_soll_und_ist ... ok +test zeilenanzahl_wird_benannt ... ok +test zeittrap_ohne_uhr_direktive_wird_abgewiesen - should panic ... ok +test fehlende_und_unerwartete_attributebene_werden_benannt ... ok +test farbabweichung_nennt_zeile_spalte_soll_und_ist ... ok +test fehlende_groessenangabe_wird_abgewiesen ... ok +test ereignisfolge_liefert_taste_maus_und_zeit_in_reihenfolge ... ok +test release_formular_vergleicht_zeichen_und_attribute_unabhaengig ... ok +test prozessfrist::frist_beendet_blockierten_testprozess ... ok +test tbc_build_erzeugt_tbc ... ok +test tbc_run_hello ... ok +test tbc_run_laufzeitfehler_exitcode ... ok +test tbc_run_stop_exitcode ... ok +test tbc_loest_include_projekt_und_run_datei_auf ... ok +test tbc_isam_open_in_transaktion_hat_eine_harte_frist ... ok +test korpus_laeuft_mit_korrekter_ausgabe ... ok + +test result: ok. 17 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.71s + + Running tests/convert_frm.rs (target/debug/deps/convert_frm-cba5b52e462e1f23) + +running 1 test +test conversion_failure_leaves_no_output ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/foreign.rs (target/debug/deps/foreign-92ee6191b667aed6) + +running 3 tests +test oeffentliche_formularprogramme_sind_reproduzierbar_bedienbar ... ignored, TB_VBDOS_REPO muss auf cout/vbdos in der dokumentierten Revision zeigen +test fehlender_oder_falscher_fremdbestand_wird_benannt ... ok +test prozessfrist::frist_beendet_blockierten_testprozess ... ok + +test result: ok. 2 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.11s + + Running tests/inventar.rs (target/debug/deps/inventar-4656d211fa731f53) + +running 17 tests +test offene_elemente_erzeugen_keinen_syntaxfehler ... ok +test bislang_signaturlose_elemente_haben_signaturen ... ok +test signatur_greift_ohne_laufzeitverhalten ... ok +test dokumentierte_elemente_werden_namentlich_abgewiesen ... ok +test non_features_nennen_eine_fundstelle_in_der_sprachreferenz ... ok +test abdeckungsstand_wird_ausgewiesen ... ok +test statusvokabular_ist_beschraenkt ... ok +test offene_elemente_haben_keine_fundstelle ... ok +test implementiert_mit_unsupported_marker_faellt_durch ... ok +test falsch_gesetzte_eigenschaft_wird_erkannt ... ok +test falscher_status_und_fehlende_runtimebindung_werden_namentlich_erkannt ... ok +test forms_inventar_stimmt_mit_der_klassentabelle_ueberein ... ok +test inventar_stimmt_mit_code_ueberein ... ok +test forms_absenkung_muss_den_richtigen_member_erreichen ... ok +test gemeinsam_dispatchte_konverter_brauchen_den_richtigen_typselektor ... ok +test jeder_inventareintrag_erreicht_hir_und_laufzeitziel ... ok +test falsche_gueltige_builtinbindung_und_entfernte_absenkung_fallen_durch ... ok + +test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s + + Running tests/project.rs (target/debug/deps/project-af9c39c0e4caf174) + +running 8 tests +test native_build_optionen_sind_explizit_und_tbc_bleibt_standard ... ok +test designer_frm_is_accepted_by_the_standalone_cli_compiler ... ok +test explicit_startup_order_and_form_selection_survive_tbc ... ok +test release_projekt_prueft_anfangsdateien_dateieffekte_und_include_fehler ... ok +test library_cli_links_without_sources_and_protects_all_inputs_and_outputs ... ok +test cli_meldet_physische_quellorte_auch_nach_verschachtelten_includes ... ok +test projekt_und_formular_laufen_nach_entfernen_saemtlicher_quellen ... ok +test erlaubte_grafik_und_benannte_nonfeatures_werden_per_cli_geprueft ... ok + +test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.39s + + Running unittests src/lib.rs (target/debug/deps/tb_export-740bf84213e12075) + +running 3 tests +test tests::publication_preserves_originals_on_conflict_failure_race_and_cancel ... ok +test tests::fehlgeschlagene_native_finalisierung_erhaelt_das_ziel ... ok +test tests::targets_versions_integrity_and_payload_bounds_are_enforced ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s + + Running unittests src/bin/tb-template.rs (target/debug/deps/tb_template-158083ae68069508) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/lib.rs (target/debug/deps/tb_frontend-668b07f10bc30f2a) + +running 52 tests +test lexer::tests::bezeichner_mit_punkt_und_unterstrich ... ok +test lexer::tests::strings_mit_doppelten_anfuehrungszeichen ... ok +test lexer::tests::suffix_macht_keyword_zum_bezeichner ... ok +test parser::tests::fehlerbehandlung ... ok +test lexer::tests::keywords_case_insensitiv ... ok +test lexer::tests::zeilenfortsetzung ... ok +test parser::tests::print_varianten ... ok +test parser::tests::zuweisung_und_aufruf ... ok +test lexer::tests::bang_ist_suffix_oder_containeroperator_nach_folgetoken ... ok +test parser::tests::operator_prioritaet ... ok +test lexer::tests::kommentare_und_rem ... ok +test lexer::tests::literal_typisierung ... ok +test parser::tests::forms_syntax ... ok +test parser::tests::select_case ... ok +test parser::tests::prozeduren ... ok +test parser::tests::schleifen ... ok +test parser::tests::typen_und_deklarationen ... ok +test parser::tests::if_block_und_einzeilig ... ok +test sema::tests::hir_konvertierung_materialisiert ... ok +test sema::tests::datei_ea_und_events ... ok +test sema::tests::deftype_regeln ... ok +test sema::tests::funktionsaufruf_und_rueckgabe ... ok +test sema::tests::argumentanzahl ... ok +test sema::tests::dreizeiler_wird_namentlich_statt_falsch_abgewiesen ... ok +test sema::tests::byref_verlangt_exakten_typ ... ok +test sema::tests::def_fn_blockform ... ok +test sema::tests::arrays_implizit_und_explizit ... ok +test sema::tests::hir_slots_aufgeloest ... ok +test sema::tests::dialoge_listindex_und_zeichenmessung_werden_abgesenkt ... ok +test sema::tests::hir_intdiv_rundet_operanden ... ok +test sema::tests::hir_byref_und_byval ... ok +test sema::tests::hir_select_wird_abgesenkt ... ok +test sema::tests::hardware_features_zur_compilezeit_abgelehnt ... ok +test sema::tests::isam_argumentanzahl_nennt_das_element ... ok +test sema::tests::createindex_ohne_obergrenze_der_spaltenzahl ... ok +test sema::tests::ereignisprozedur_signatur_und_normale_unterstrich_sub ... ok +test sema::tests::isam_anweisung_parst_ohne_diagnose ... ok +test sema::tests::konstantenfaltung ... ok +test sema::tests::builtins_typen ... ok +test sema::tests::label_pruefung ... ok +test sema::tests::mid_anweisung ... ok +test sema::tests::option_explicit ... ok +test sema::tests::isam_satzargument_wird_typgeprueft ... ok +test sema::tests::eigenschaftstyp_schreibbarkeit_bang_und_hir_index ... ok +test sema::tests::rollback_all_wird_als_sentinel_abgesenkt ... ok +test sema::tests::typeof_form_control_und_form_metabefehl ... ok +test sema::tests::objektpfade_werden_namentlich_geprueft_und_udt_bleibt_unveraendert ... ok +test sema::tests::kein_isam_element_ist_unbekannter_bezeichner ... ok +test sema::tests::shared_und_common ... ok +test sema::tests::typkonflikt_wird_erkannt ... ok +test sema::tests::unbekanntes_unterprogramm ... ok +test sema::tests::udt_feldtypen ... ok + +test result: ok. 52 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/corpus.rs (target/debug/deps/corpus-0371f2991a3b061a) + +running 1 test +test korpus_parst_und_wird_typgeprueft ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/editing.rs (target/debug/deps/editing-01467d91310d70f2) + +running 4 tests +test incomplete_is_parser_context_not_a_second_grammar ... ok +test normalization_protects_tokens_and_is_idempotent ... ok +test deftype_context_does_not_leak_from_another_procedure ... ok +test declaration_maintenance_and_procedure_generation_are_transactional ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/lib.rs (target/debug/deps/tb_ide-43621e6718da8b87) + +running 3 tests +test export::tests::delayed_result_is_published_only_after_ui_validation_and_success_stays_success ... ok +test export::tests::replaced_library_invalidates_pending_export_even_with_same_length ... ok +test export::tests::cancelled_superseded_changed_and_foreign_jobs_never_publish ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s + + Running unittests src/main.rs (target/debug/deps/tb-f285a33b6fdb6251) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/app.rs (target/debug/deps/app-d3d6e33413d63d0f) + +running 20 tests +test theme_color_commands_use_explicit_values_and_never_modify_terminal_palette ... ok +test executable_target_validation_and_missing_template_are_honest ... ok +test start_snapshot_and_reference_menus_have_all_commands ... ok +test dispatcher_keeps_function_keys_and_copy_out_of_basic_input ... ok +test designer_form_list_and_context_availability_match_the_active_window ... ok +test modal_focus_and_dirty_project_cancel_preserve_document ... ok +test windows_restore_geometry_and_resize_without_document_loss ... ok +test theme_windows_erase_desktop_and_underlying_windows_on_every_redraw ... ok +test options_apply_persist_across_bases_and_preserve_unsaved_values_on_error ... ok +test clicking_project_members_and_dialog_choices_transfers_focus_and_applies_values ... ok +test theme_designer_chrome_and_handles_preserve_program_palette ... ok +test status_and_project_buttons_use_the_keyboard_command_path ... ok +test mouse_focus_is_modal_and_program_abort_is_not_editor_copy ... ok +test debugger_reports_absent_library_source_and_can_step_back_to_caller ... ok +test file_picker_save_conflict_and_project_replacement_use_real_events ... ok +test finalization_failure_is_reported_and_preserves_existing_output ... ok +test exit_with_partial_save_retains_dialog_and_unsaved_documents ... ok +test real_library_export_uses_dirty_include_and_mouse_without_runtime_template ... ok +test export_dialogs_validate_and_render_all_results_without_creating_files ... ok +test theme_contrast_covers_rendered_states_and_rejects_bad_pairs ... ok + +test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s + + Running tests/debugger.rs (target/debug/deps/debugger-18aeee8ea147e9f4) + +running 6 tests +test includes_and_deleted_marks_do_not_bind_to_foreign_statements ... ok +test form_handler_keys_and_old_revision_cursor_guard ... ok +test immediate_wait_run_transition_watchpoint_and_trace_are_session_owned ... ok +test dispatcher_marks_edits_rebind_and_readonly_watches ... ok +test calls_procedure_step_cursor_history_and_restart ... ok +test calls_mouse_inspection_instant_key_delete_and_error_window ... ok + +test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s + + Running tests/designer.rs (target/debug/deps/designer-1f0dd9e883e87225) + +running 18 tests +test menu_indent_outdent_rename_and_field_changes_have_one_undo ... ok +test clipboard_children_arrays_and_delete_preserve_code ... ok +test property_bar_types_readonly_and_no_status_line ... ok +test binary_designer_import_requires_text_target_and_compiles ... ok +test imported_type_shadow_is_not_an_object_reference_during_rename ... ok +test event_array_signature_twice_and_shared_form_identity ... ok +test bound_rename_across_documents_is_atomic_and_undo_restores_all ... ok +test container_multiselect_keyboard_drag_resize_and_undo ... ok +test rename_preserves_shadowed_names_and_handles_form_aliases_and_include_calls ... ok +test menu_hierarchy_arrays_shortcuts_and_palette_use_events ... ok +test toolbox_double_click_tool_drag_grid_and_window_form_selection ... ok +test indexed_controls_merge_atomically_with_bindings_and_undo ... ok +test events_with_the_same_name_are_local_to_their_form ... ok +test property_menu_buttons_palette_drag_and_modal_mouse_are_connected ... ok +test shared_include_ambiguity_aborts_rename_and_event_defaults_use_includes ... ok +test all_metadata_tools_persist_and_preview_matches_runtime_without_events ... ok +test all_eight_handles_resize_transactionally_and_preserve_identity_after_structure_edits ... ok +test existing_default_typed_event_and_all_metadata_signatures_compile ... ok + +test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s + + Running tests/documents.rs (target/debug/deps/documents-6a65482da983e004) + +running 15 tests +test unrepresentable_save_paths_fail_before_writing_or_changing_documents ... ok +test save_plan_prevents_same_destination_and_project_overwrite ... ok +test shared_views_text_import_and_undo_are_document_transactions ... ok +test failed_open_add_and_cancel_do_not_replace_existing_documents ... ok +test aliases_share_documents_and_form_code_offsets_match_saved_text ... ok +test binary_import_only_saves_to_explicit_text_target_and_preserves_original_forever ... ok +test startup_removal_requires_explicit_replacement_and_never_deletes_a_file ... ok +test project_save_as_rebases_members_and_keeps_include_targets ... ok +test edited_include_wins_in_both_modules_without_writing_the_expansion ... ok +test libraries_are_binary_members_with_relative_save_as_and_no_source_views ... ok +test external_changes_and_save_as_collisions_need_explicit_decisions ... ok +test cursor_after_shortening_uses_original_position_and_open_after_save_uses_fresh_disk ... ok +test module_save_as_rebases_includes_and_failed_save_does_not_change_identity_or_text ... ok +test partial_save_preserves_unsaved_data_and_does_not_finish_close ... ok +test project_create_save_reopen_preserves_forms_members_startup_and_cli_sources ... ok + +test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s + + Running tests/editor.rs (target/debug/deps/editor-b6dc665e95525030) + +running 7 tests +test search_scope_direction_wrap_and_shortening_replace_all ... ok +test crlf_navigation_word_boundaries_readonly_and_normalization_keep_views ... ok +test cua_unicode_overwrite_wordstar_and_shared_undo ... ok +test line_leave_incomplete_invalid_disabled_and_current_revisions ... ok +test includes_and_diagnostic_selection_use_original_physical_files ... ok +test procedures_and_shared_save_hook_preserve_drafts_and_frm_code ... ok +test external_include_revision_and_project_context_declarations ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s + + Running tests/execution.rs (target/debug/deps/execution-bf913fdae7aacbc3) + +running 13 tests +test ide_and_cli_run_wrapper_match_input_time_and_forms_script ... ok +test f5_input_pause_copy_and_single_delivery_keep_the_same_vm ... ok +test shell_request_is_resumed_once_and_error_is_basic_error ... ok +test named_run_of_current_target_uses_edited_sources ... ok +test print_uses_utf8_protected_output_and_does_not_mutate_source ... ok +test comment_only_source_change_also_requires_revision_choice ... ok +test output_viewports_resize_and_end_preserve_buffer_and_basic_colors ... ok +test changed_paused_source_requires_explicit_old_revision_or_restart ... ok +test explicit_end_and_system_end_visible_forms_but_natural_end_keeps_them_live ... ok +test restart_command_run_targets_and_missing_target_preserve_documents ... ok +test restart_drops_files_data_traps_and_queued_actions ... ok +test startup_selection_matches_shared_cli_pipeline_and_legacy_mak ... ok +test platform_probe_records_each_basic_key_once_and_keeps_ide_keys_out ... ok + +test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s + + Running tests/help.rs (target/debug/deps/help-ff16d5fb3c397804) + +running 11 tests +test offline_help_child ... ok +test markdown_blocks_escapes_links_and_unicode_layout ... ok + +running 1 test +test catalog_links_and_missing_targets_are_checked ... ok +test right_click_configuration_and_external_link_follow ... ok +test links_history_resize_scroll_and_focus_use_real_events ... ok +test every_command_and_forms_alias_resolves_and_invalid_alias_fails ... ok +test twenty_back_steps_end_of_contents_and_all_entries ... ok +test offline_help_child ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 10 filtered out; finished in 0.05s + +test help_works_from_a_directory_without_checkout ... ok +test help_preserves_fullscreen_and_does_not_modify_designer_or_source ... ok +test context_functions_properties_commands_and_unknown_queries ... ok +test code_and_tables_remain_reachable_after_resize_and_horizontal_scroll ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s + + Running unittests src/lib.rs (target/debug/deps/tb_runner-d3339a5a0df9c7dd) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/bin/tbrt.rs (target/debug/deps/tbrt-a6c3f62502f5f188) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests src/lib.rs (target/debug/deps/tb_runtime-6b2bc969f5367a62) + +running 140 tests +test builtins::tests::key_stop_merkt_einmal_und_laesst_alle_tasten_auch_nach_on_lesbar ... ok +test builtins::tests::zonenquelle_ausfall_und_erholung_gelten_fuer_alle_zeitfunktionen ... ok +test console::tests::volle_zone_springt_zur_uebernaechsten ... ok +test builtins::tests::nicht_getrappte_taste_bleibt_im_strom ... ok +test builtins::tests::setuevent_meldet_das_benutzerereignis ... ok +test builtins::tests::mausereignisse_haeufen_sich_nicht_an ... ok +test builtins::tests::input_s_dispatch_bewahrt_codepointreste_auch_ohne_vm ... ok +test builtins::tests::off_wirkt_auf_bereits_wartende_tasten ... ok +test builtins::tests::getrappte_taste_verlaesst_den_eingabestrom ... ok +test builtins::tests::sigint_ohne_aktiven_trap_bleibt_abbruch ... ok +test console::tests::druckzone_folgt_dem_cursor_nach_locate ... ok +test builtins::tests::builtin_ueber_tabelle ... ok +test builtins::tests::benutzertaste_ueber_key_anweisung ... ok +test builtins::tests::signal_aus_dem_host_meldet_den_trap ... ok +test builtins::tests::signal_stop_merkt_beide_quellen_und_off_verwirft ... ok +test builtins::tests::benutzertaste_ohne_umschalt_bleibt_im_strom ... ok +test console::tests::druckzonen ... ok +test builtins::tests::stringfunktionen_randfaelle ... ok +test console::tests::zahlen_mit_vorzeichenspalte ... ok +test datetime::tests::fester_versatz_verschiebt_genau ... ok +test datetime::tests::gueltigkeitspruefung ... ok +test datetime::tests::programmversatz_kommt_hinzu ... ok +test datetime::tests::serienwert_und_rueckumwandlung ... ok +test datetime::tests::tageszeit ... ok +test datetime::tests::text_in_serienwert ... ok +test datetime::tests::wochentag_sonntag_ist_eins ... ok +test datetime::tests::zaehlweise_des_vorbilds ... ok +test errors::tests::bekannte_codes ... ok +test errors::tests::forms_und_isam_codes ... ok +test errors::tests::unbelegte_codes_sind_unprintable ... ok +test fileio::tests::felder_einer_input_zeile ... ok +test fileio::tests::modus_aus_kurzsyntax ... ok +test fileio::tests::festes_feld_ist_inhaltsunabhaengig_gleich_lang ... ok +test fileio::tests::muster_mit_stern_und_fragezeichen ... ok +test fileio::tests::rset_schneidet_ab_und_richtet_rechts_aus ... ok +test finanz::tests::abschreibungen ... ok +test finanz::tests::barwert_und_endwert_sind_gegenlaeufig ... ok +test finanz::tests::endwert_einer_rentenzahlung ... ok +test finanz::tests::irr_ohne_vorzeichenwechsel_ist_fehler ... ok +test finanz::tests::kapitalwert_und_interner_zinsfuss ... ok +test finanz::tests::mirr_liegt_zwischen_den_zinsen ... ok +test finanz::tests::nper_zaehlt_die_perioden ... ok +test finanz::tests::ungueltige_argumente ... ok +test finanz::tests::zins_und_tilgung_ergeben_die_zahlung ... ok +test finanz::tests::zinssatz_wird_zurueckgerechnet ... ok +test format::tests::currency_darstellung ... ok +test format::tests::double_darstellung ... ok +test format::tests::ganzzahlen ... ok +test format::tests::single_darstellung ... ok +test format::tests::val_parsen ... ok +test host::tests::capture_host_haelt_zeichen_und_attribut ... ok +test host::tests::maus_und_tasten_behalten_ihre_reihenfolge ... ok +test host::tests::virtuelle_uhr_laeuft_nur_wenn_gestellt ... ok +test host::tests::vorbereitete_zeile_wird_zu_tasten ... ok +test host::tests::groessenaenderung_und_abbruch_als_ereignis ... ok +test host::tests::verzoegertes_ereignis_kommt_nach_der_anzeige ... ok +test isam::tests::absteigende_spalte_kehrt_die_ordnung_um ... ok +test isam::tests::nullbyte_im_text_stoert_den_abschluss_nicht ... ok +test isam::tests::praefix_ende_zaehlt_hoch ... ok +test isam::tests::beschaedigte_datei_meldet_fehler_88 ... ok +test datetime::tests::versatz_gilt_je_zeitpunkt ... ok +test datetime::tests::versatz_liegt_im_gueltigen_bereich ... ok +test isam::tests::kodierung_erhaelt_die_ordnung_bei_zufallspaaren ... ok +test isam::tests::prozessfrist::frist_beendet_blockierten_testprozess ... ok +test isam::tests::ohne_transaktion_kein_protokoll ... ok +test isam::tests::close_beendet_keine_transaktion ... ok +test isam::tests::jede_satzoperation_erzeugt_einen_protokolleintrag ... ok +test isam::tests::satz_roundtrip_ueber_alle_feldtypen ... ok +test isam::tests::textabschluss_ordnet_praefix_vor_laengerem_text ... ok +test isam::tests::pfadaliase_teilen_transaktion_und_ruecknahme ... ok +test isam::tests::ungueltige_namen_werden_abgewiesen ... ok +test isam::tests::neue_tabellen_und_aktive_indizes_verschwinden_bei_ruecknahme ... ok +test isam::tests::saetze_nach_close_aller_bindungen_zuruecknehmen ... ok +test screen::tests::blink_wird_als_hell_simuliert ... ok +test isam::tests::gescheitertes_createindex_hinterlaesst_keinen_index ... ok +test screen::tests::breites_zeichen_am_rechten_rand_bricht_ganz_um ... ok +test isam::tests::geloeschte_satz_id_wird_nicht_neu_vergeben ... ok +test screen::tests::breites_zeichen_belegt_zwei_zellen ... ok +test isam::tests::nicht_festgeschriebene_transaktion_verfaellt ... ok +test isam::tests::delete_pufferfehler_erhaelt_saetze_indizes_und_cursor ... ok +test screen::tests::locate_auf_fortsetzung_trifft_den_zeichenanfang ... ok +test screen::tests::locate_prueft_grenzen ... ok +test isam::tests::deletetable_loest_alle_betroffenen_bindungen ... ok +test screen::tests::print_schreibt_und_bewegt_cursor ... ok +test isam::tests::indexeintraege_stehen_in_schluesselreihenfolge ... ok +test screen::tests::dynamische_groesse_und_resize ... ok +test screen::tests::resize_folgt_vollem_scrollbereich ... ok +test screen::tests::rueckschritt_loescht_ein_breites_zeichen_ganz ... ok +test screen::tests::resize_klemmt_cursor_und_scrollbereich ... ok +test screen::tests::scrollen_am_unteren_rand ... ok +test screen::tests::resize_klemmt_nur_den_unteren_rand_wenn_der_bereich_bleibt ... ok +test screen::tests::ueberschreiben_einer_haelfte_leert_die_andere ... ok +test screen::tests::umbruch_am_rechten_rand ... ok +test screen::tests::ui_zeile_bleibt_am_rand_ohne_umbruch_oder_scrollen ... ok +test screen::tests::unicode_zeichen_belegen_eine_zelle ... ok +test screen::tests::view_print_begrenzt_scrollen ... ok +test isam::tests::cursor_ueberlebt_eine_satzaenderung ... ok +test snapshot::tests::breites_zeichen_erscheint_einmal ... ok +test isam::tests::struktur_undo_prueft_puffer_vor_dem_loeschen ... ok +test snapshot::tests::getrimmt_auf_die_belegte_flaeche ... ok +test snapshot::tests::leerer_bildschirm_ergibt_leeren_snapshot ... ok +test snapshot::tests::locate_erweitert_die_flaeche ... ok +test isam::tests::hoehere_formatversion_wird_abgewiesen ... ok +test snapshot::tests::mit_farben_kommt_die_attributebene ... ok +test snapshot::tests::nachgestellte_leerzeichen_bleiben_erhalten ... ok +test snapshot::tests::ohne_farben_keine_attributebene ... ok +test traps::tests::aus_verwirft_auch_das_gemerkte ... ok +test traps::tests::aus_verwirft_kuenftige ... ok +test traps::tests::beide_umschaltbits_gelten_gleich ... ok +test traps::tests::benutzertaste_braucht_umschaltzustand_und_scancode ... ok +test traps::tests::event_off_verwirft_ereignisse_und_laesst_die_zustaende ... ok +test traps::tests::genauer_trap_geht_dem_sammeltrap_vor ... ok +test traps::tests::gestoppt_merkt_genau_eines ... ok +test traps::tests::gosub_null_schaltet_den_trap_ab ... ok +test traps::tests::kein_wiedereintritt_waehrend_der_handler_laeuft ... ok +test traps::tests::key_null_faengt_alle_tasten_der_tabelle ... ok +test traps::tests::off_im_handler_ueberlebt_das_return ... ok +test traps::tests::ohne_trap_kostet_nichts ... ok +test traps::tests::reihenfolge_key_vor_timer_vor_uevent_vor_signal ... ok +test traps::tests::return_schaltet_sonst_selbsttaetig_ein ... ok +test traps::tests::uebersprungene_fristen_zaehlen_als_eine ... ok +test traps::tests::vordefinierte_taste_wird_ueber_den_scancode_erkannt ... ok +test traps::tests::zeit_wird_erst_nach_der_frist_faellig ... ok +test using::tests::exponentialform ... ok +test using::tests::feldueberlauf_bekommt_prozentzeichen ... ok +test using::tests::format_wird_wiederverwendet ... ok +test using::tests::literale_und_unterstrich ... ok +test using::tests::numerisches_feld_mit_nachkommastellen ... ok +test using::tests::ohne_feld_aber_mit_werten_ist_fehler_5 ... ok +test using::tests::ohne_feld_und_ohne_werte_bleibt_der_text ... ok +test using::tests::stringfelder ... ok +test using::tests::tausendertrennung ... ok +test using::tests::vorzeichenfuehrung ... ok +test using::tests::waehrung_und_sterne ... ok +test value::tests::array_indexpruefung ... ok +test value::tests::banker_rounding ... ok +test value::tests::currency_rundung ... ok +test value::tests::overflow_bei_konvertierung ... ok +test isam::tests::savepoints_nehmen_index_und_tabellenstrukturen_zurueck ... ok +test isam::tests::symlink_neuanlage_behaelt_die_dateiidentitaet ... ok + +test result: ok. 140 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s + + Running unittests src/lib.rs (target/debug/deps/tb_ui-95ce53373c09fcd8) + +running 66 tests +test forms::tests::screen_folgt_resize ... ok +test forms::tests::defaults_bereich_und_implizites_laden ... ok +test forms::tests::hide_entlaedt_nicht_und_unload_ist_abbrechbar ... ok +test forms::tests::optionen_gruppieren_nach_unmittelbarem_container ... ok +test forms::tests::screen_meldet_oberstes_formular_und_aktives_control ... ok +test forms::tests::arrays_und_designzeitfehler ... ok +test forms::tests::modalfehler_400_bis_403 ... ok +test forms::tests::gleichzeitig_faellige_timer_laufen_nach_name ... ok +test forms::tests::combobox_dropdown_closes_on_focus_change_and_hide ... ok +test forms::tests::menuregeln_weisen_separator_und_titel_shortcuts_ab ... ok +test forms::tests::spin_zaehlt_zyklisch_und_wiederholt_nach_interval ... ok +test forms::tests::timerarrays_holen_nur_aktive_zeit_nach_und_sortieren_nach_name_und_index ... ok +test forms::tests::timer_neustart_verwirft_alte_fristen_und_ereignisse ... ok +test frm::tests::binary_layout_preserves_arrays_and_container_hierarchy ... ok +test frm::tests::binary_reader_rejects_out_of_range_property_with_offset ... ok +test forms::tests::zeichenbilder_aller_klassen_und_buttonhoehen ... ok +test frm::tests::binary_class_specific_properties_match_the_reference_exports ... ok +test frm::tests::binary_reader_rejects_magic_and_unknown_structure_with_offset ... ok +test forms::tests::tabfolge_ueberspringt_und_laeuft_rueckwaerts ... ok +test forms::tests::indexed_containers_preserve_parent_geometry_and_option_groups ... ok +test forms::tests::freier_formularklick_und_doppelklick_werden_zugestellt ... ok +test frm::tests::binary_strings_and_header_flags_map_to_the_named_properties ... ok +test forms::tests::simple_combo_zeichnet_listeninhalt_auswahl_und_begrenzung ... ok +test frm::tests::binary_strings_are_decoded_from_cp437 ... ok +test forms::tests::menues_zeichnen_und_navigieren_sechs_ebenen ... ok +test frm::tests::explicit_default_is_preserved_until_canonical_write ... ok +test forms::tests::fokus_tab_access_default_und_eingabeprioritaet ... ok +test frm::tests::reads_nested_form_and_preserves_source_exactly ... ok +test frm::tests::spin_symbol_wird_als_bedienbares_control_erkannt ... ok +test frm::tests::rejects_version_class_property_value_and_open_block_with_location ... ok +test forms::tests::text_liste_option_scroll_picture_und_dateisystem ... ok +test frm::tests::canonical_index_zero_remains_an_array_and_array_parents_are_preserved ... ok +test frm::tests::text_form_control_arrays_share_one_catalog_object_and_keep_indices ... ok +test frm::tests::unsupported_binary_property_is_named_and_unclaimed_strings_still_fail ... ok +test frm::tests::writes_no_properties_for_default_only_control ... ok +test frm::tests::writes_documented_d1_and_roundtrips_description ... ok +test frm::tests::writes_read_only_boolean_only_when_it_differs_from_false ... ok +test frm::tests::unsupported_custom_control_is_named_and_not_emitted_as_screen ... ok +test host::tests::ausserhalb_der_flaeche_wird_verworfen ... ok +test frm_pcode::tests::embedded_include_is_a_comment_but_literals_remain_unchanged ... ok +test host::tests::backtab_ist_tab_mit_shift_auch_ohne_modifier ... ok +test host::tests::letzte_zelle_liegt_noch_drin ... ok +test frm_pcode::tests::decodes_defint_and_vbdos_isam_tokens ... ok +test frm_pcode::tests::decodes_vbdos_declarations_without_losing_type_or_bounds ... ok +test frm::tests::reads_real_vbdos_form_with_complete_documented_description ... ok +test frm_pcode::tests::resets_block_local_default_types_before_the_next_block ... ok +test frm_pcode::tests::next_trennt_eine_vorangehende_anweisung_auch_ohne_newline_token ... ok +test host::tests::nach_groessenaenderung_gilt_die_neue_flaeche ... ok +test host::tests::maus_zaehlt_ab_eins ... ok +test host::tests::rollrad_hat_keine_entsprechung ... ok +test host::tests::sondertaste_traegt_fuehrendes_nullzeichen ... ok +test host::tests::strg_c_ist_abbruch ... ok +test host::tests::umschaltzustand_als_bitfeld ... ok +test host::tests::umschaltzustand_der_taste_wird_mitgefuehrt ... ok +test host::tests::zeichentaste_wird_zu_inkey_form ... ok +test screen::tests::farbabbildung ... ok +test signale::tests::marke_wird_zu_kennung_und_verfaellt_danach ... ok +test signale::tests::echtes_signal_setzt_die_marke ... ok +test signale::tests::sigint_hat_vorrang_vor_sigterm ... ok +test forms::tests::z_reihenfolge_dragdrop_und_timerreihenfolge ... ok +test forms::tests::listenauswahl_bleibt_beim_einfuegen_und_entfernen_konsistent ... ok +test forms::tests::forms_dialoge_liefern_gruppen_eingabe_und_feste_groesse ... ok +test forms::tests::sorted_wechsel_erhaelt_auch_die_auswahl_zwischen_duplikaten ... ok +test forms::tests::zustandsfarben_laufen_fuer_alle_controls_ueber_denselben_zeichenpfad ... ok +test terminal::tests::terminal_cleanup_on_normal_error_and_partial_initialization ... ok +test forms::tests::listenrenderer_haelt_zellgrenzen_auch_an_bildschirmraendern_ein ... ok + +test result: ok. 66 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.60s + + Running unittests src/lib.rs (target/debug/deps/tb_vm-2a4538183acbb98c) + +running 16 tests +test bytecode::tests::instr_roundtrip ... ok +test bytecode::tests::unbekannte_version_wird_abgelehnt ... ok +test bytecode::tests::tbc_roundtrip ... ok +test codegen::tests::data_read_restore ... ok +test codegen::tests::fehlerbehandlung_emit ... ok +test codegen::tests::gosub_und_on_goto ... ok +test codegen::tests::if_mit_fixup ... ok +test codegen::tests::for_mit_dynamischem_step ... ok +test codegen::tests::tbc_roundtrip_ueber_codegen ... ok +test codegen::tests::for_mit_konstantem_step ... ok +test codegen::tests::string_konkatenation ... ok +test codegen::tests::arrays_dim_und_zugriff ... ok +test codegen::tests::vergleich_und_logik ... ok +test codegen::tests::ausdruck_monomorph_mit_conv ... ok +test codegen::tests::function_liefert_wert ... ok +test codegen::tests::prozedur_und_byref ... ok + +test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/cooperative.rs (target/debug/deps/cooperative-acdd5e7adb1bd680) + +running 7 tests +test sleep_deadline_survives_pause_and_does_not_pop_argument_twice ... ok +test finite_slices_preserve_events_without_clock_queries ... ok +test partial_console_operations_keep_prompt_arguments_and_assignment ... ok +test common_dialog_external_call_keeps_byref_arguments_until_completion ... ok +test pending_dialog_keeps_physical_resize_and_modeless_handler_finishes_after_hide ... ok +test dialogs_keep_partial_text_focus_and_caller_arguments ... ok +test modal_and_modeless_forms_resume_handlers_across_tiny_budgets ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/debugger.rs (target/debug/deps/debugger-2aaa51d59ed630d5) + +running 14 tests +test gosub_step_over_breakpoint_priority_and_temporary_target_cleanup ... ok +test immediate_handler_resume_and_break_on_errors ... ok +test same_line_calls_and_immediate_do_not_retrigger_a_line_breakpoint ... ok +test immediate_handler_exit_and_cached_new_imports_are_safe ... ok +test set_next_rejects_else_and_case_entry_but_allows_peer_statements ... ok +test break_continue_loop_and_statement_steps ... ok +test set_next_rejects_loop_gosub_handler_and_pending_operations_atomically ... ok +test step_over_recursive_frames_history_and_safe_jump ... ok +test form_event_breakpoint_and_step_over_keep_the_event_frame ... ok +test include_identity_qualified_globals_udts_and_older_frames ... ok +test watches_immediate_byref_and_errors_preserve_continuation ... ok +test immediate_wait_interrupt_nested_error_end_and_run ... ok +test watches_never_initialize_arrays_or_run_user_functions_and_keep_selected_context ... ok +test watchpoint_history_ring_and_error_differential ... ok + +test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/events.rs (target/debug/deps/events-2f0766815a3e98d6) + +running 33 tests +test doevents_verhindert_rekursion_derselben_forms_prozedur ... ok +test fehlender_ereignispfad_wird_namentlich_erkannt ... ok +test fokus_handler_laufen_geordnet_bis_zur_rueckkehr ... ok +test handler_eingabe_und_stop_bewahren_die_aeussere_eingabe ... ok +test lokaler_error_handler_nach_trap_verwirft_abgebrochene_teileingabe ... ok +test randomize_eingabe_teilt_den_fortsetzbaren_konsolenpfad ... ok +test input_redo_verliert_weder_referenzen_noch_teiltext_beim_trap ... ok +test offenes_menu_sperrt_traps_und_wartende_forms_timer_an_allen_zustellpunkten ... ok +test ohne_zeitbedarf_keine_uhrabfrage_und_keine_mausansammlung ... ok +test eof_leert_angenommene_eingaben_bei_modalen_und_modellosen_forms ... ok +test formular_tastatur_fallback_fuehrt_alle_drei_basic_handler_aus ... ok +test intervallaenderung_im_handler_verwirft_bereits_faellige_altintervalle ... ok +test dialog_erhaelt_stop_markierung_unverbrauchter_tasten ... ok +test eof_im_dialog_eines_formularhandlers_beendet_die_ereignispumpe ... ok +test review_gleichzeitig_key_und_uevent_behalten_prioritaet ... ok +test beide_signale_werden_zugestellt_und_beginnen_in_quellreihenfolge ... ok +test review_menu_schliessen_stellt_pending_trap_vor_erneutem_warten_zu ... ok +test return_label_verwirft_abgebrochene_eingabe_und_ausdruck ... ok +test review_maus_vor_getrappter_taste ... ok +test review_modale_eingabe_vor_eof_wird_zugestellt ... ok +test input_fortsetzung_erhaelt_teiltext_ausdruck_und_byref_ziel ... ok +test timer_waehrend_input_wird_vor_erneutem_warten_zugestellt ... ok +test review_signal_waehrend_blockierender_eingabe ... ok +test unload_aus_unload_handler_ruft_dieselbe_prozedur_nicht_rekursiv_auf ... ok +test spaete_timeraktivierung_nutzt_hostzeit_auch_ueber_control_parameter ... ok +test key_on_off_stop_gelten_fuer_alle_konsoleneingaben ... ok +test taste_maus_und_trap_behalten_die_annahmereihenfolge ... ok +test review_objektargument_darf_gotfocus_nicht_vorziehen ... ok +test registrierte_form_ereignisse_erreichen_basic_aus_realen_quellen ... ok +test shell_und_irr_funktionssignaturen_erreichen_die_runtime ... ok +test sleep_folgt_nur_der_hostfrist_und_forms_timer_beendet_es ... ok +test registrierte_control_ereignisse_erreichen_basic_aus_realen_quellen ... ok +test prozessfrist::frist_beendet_blockierten_testprozess ... ok + +test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s + + Running tests/incremental.rs (target/debug/deps/incremental-ef01ad977c2204da) + +running 4 tests +test unused_constants_do_not_invalidate_independent_units_and_declare_changes_do ... ok +test includes_source_ids_data_and_forms_relink_without_patching_old_products ... ok +test cached_private_edits_parse_and_compile_only_changed_modules ... ok +test constants_types_common_removed_symbols_and_order_match_full_compiler ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/library.rs (target/debug/deps/library-0b9e1b471b1e7297) + +running 9 tests +test source_debug_context_keeps_module_ids_when_library_is_between_sources ... ok +test source_and_library_have_identical_types_constants_common_data_byref_and_init_order ... ok +test contracts_reject_result_common_bounds_and_invalid_declarations ... ok +test library_include_locations_keep_physical_lines_and_basic_erl ... ok +test library_source_locations_and_run_restart_are_preserved ... ok +test unused_declare_is_not_an_import_but_references_in_any_body_must_resolve ... ok +test two_source_free_libraries_with_typed_open_imports_and_diagnostics ... ok +test library_container_rejects_truncation_versions_lengths_and_references ... ok +test separate_form_libraries_remap_nested_objects_initials_arrays_and_events ... ok + +test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/project.rs (target/debug/deps/project-7ae350d75d21dcb2) + +running 7 tests +test diagnose_im_include_und_echte_duplikate_bleiben_sichtbar ... ok +test typreferenzen_signaturen_und_option_base_ueber_modulgrenzen ... ok +test module_includes_erl_breakpoints_und_inspektion_behalten_ihren_ursprung ... ok +test lokale_prozeduren_shared_common_und_wiederholte_includes_bleiben_getrennt ... ok +test initialisierungen_def_fn_und_modulhandler_haben_eigene_quellorte ... ok +test zwei_formulare_mit_gleichen_controls_und_arrays_laufen_aus_dem_kompilat ... ok +test beschaedigte_container_werden_vor_der_ausfuehrung_abgewiesen ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/project_io.rs (target/debug/deps/project_io-76f82da2b295b346) + +running 7 tests +test case_insensitive_parent_lookup_works_from_relative_base_without_changing_cwd ... ok +test overlays_keep_original_files_and_distinct_module_contexts ... ok +test documented_mak_example_is_accepted_by_the_shared_loader ... ok +test relative_include_precedes_search_paths_and_virtual_files_are_resolved ... ok +test startup_metadata_roundtrip_and_invalid_contracts ... ok +test cycle_missing_include_and_literal_directives_are_distinguished ... ok +test tbl_members_move_save_as_order_startup_and_same_size_cache_replacement ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s + + Running tests/project_regressions.rs (target/debug/deps/project_regressions-88b074fd28a1a09a) + +running 16 tests +test diagnostik_bei_literalen_im_include_hat_die_exakte_spalte ... ok +test spaetere_common_konflikte_und_doppelte_module_werden_am_ursprung_gemeldet ... ok +test v6_linkerdiagnose_nennt_den_urspruenglichen_dateiort ... ok +test prozedurlokaler_deftype_veraendert_keine_nachfolgende_signatur ... ok +test v5_load_und_unload_loesen_den_expliziten_container_auf ... ok +test v3_form_metabefehle_erzeugen_getrennte_formularobjekte ... ok +test debugger_unterscheidet_typisierte_scalar_und_arraynamen ... ok +test common_vertraege_und_linkfehler_haben_echte_quellorte ... ok +test gemischte_frm_und_form_module_haben_getrennte_ereignisbindungen ... ok +test modulbreakpoint_rundlauf_inspektion_und_numerische_erl_bleiben_getrennt ... ok +test v4_common_behaelt_typidentitaet_und_initialisiert_arrays_einmal ... ok +test v2_importierte_deklarationen_behalten_kontext_und_abhaengigkeiten ... ok +test v1_zweige_und_schleifen_behalten_eigene_quellorte ... ok +test common_arrays_behalten_dynamische_grenzen_und_kompatible_offene_deklarationen ... ok +test importkontext_bleibt_auch_bei_abweichenden_lokalen_definitionen_erhalten ... ok +test schleifengrenzen_tragen_breakpoint_include_und_resume ... ok + +test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + Running tests/vm.rs (target/debug/deps/vm-4bcfa272723580f5) + +running 114 tests +test common_dialog_registrierung_setzt_byref_erfolg ... ok +test data_read_restore ... ok +test banker_rounding_cint ... ok +test byref_wirkt_zurueck ... ok +test breakpoint_haelt_an_und_setzt_fort ... ok +test data_typkonflikt_fehler_13 ... ok +test clipboard_und_printer_objekte_haben_laufzeitwirkung ... ok +test byref_auf_arrayelement ... ok +test doevents_liefert_null ... ok +test ausgabe_erscheint_vor_der_eingabe ... ok +test default_button_hat_vorrang_und_beendet_modales_formular ... ok +test color_prueft_wertebereich ... ok +test cls_setzt_cursor_zurueck ... ok +test division_durch_null ... ok +test def_fn_im_modulkontext ... ok +test do_loop_varianten ... ok +test eingabe_wird_geechot_und_rueckschritt_loescht ... ok +test einzelschritt ... ok +test doevents_stellt_zu ... ok +test erl_liefert_zeilennummer ... ok +test erl_null_ohne_zeilennummern ... ok +test erl_nennt_die_fehlerzeile_nicht_die_handlerzeile ... ok +test error_anweisung ... ok +test end_und_system ... ok +test fehlende_ereignisprozedur_verfaellt_und_typeof_prueft_klasse ... ok +test exit_for_und_do ... ok +test fehler_im_handler_ist_fatal ... ok +test for_mit_negativem_step ... ok +test for_mit_dynamischem_step ... ok +test for_ohne_durchlauf ... ok +test fester_versatz_verschiebt_die_uhr ... ok +test fehler_im_trap_handler_erreicht_den_modulweiten_handler ... ok +test event_off_klammert_die_zustellung ... ok +test groessenaenderung_wirkt_zur_laufzeit ... ok +test form_load_laeuft_vor_dem_sichtbarsetzen ... ok +test inkey_liefert_zeichen_und_sondertaste ... ok +test gemischte_arithmetik ... ok +test form_load_laeuft_einmal_und_unload_cancel_verhindert_entladen ... ok +test grafik_line_paint_und_view_zeichnen_in_den_zellenpuffer ... ok +test inkey_ohne_taste_ist_leer ... ok +test input_mit_redo ... ok +test ganzes_array_uebergeben ... ok +test gosub_null_schaltet_den_trap_ab ... ok +test gosub_return_und_fehler_3 ... ok +test input_s_liest_genau_n_zeichen_ohne_echo ... ok +test intdiv_rundet_operanden_vor ... ok +test function_und_rekursion ... ok +test kennung_ausserhalb_des_bereichs_ist_fehler_5 ... ok +test klammern_erzwingen_byval ... ok +test line_input_liest_ganze_zeile ... ok +test len_liefert_die_feste_satzbreite_eines_udt ... ok +test klassischer_timer_trap_ruht_solange_das_menu_offen_ist ... ok +test input_s_teilt_sondertasten_und_bewahrt_rest_fuer_inkey ... ok +test logik_bitweise ... ok +test locate_ausserhalb_loest_fehler_5_aus ... ok +test mid_anweisung_mutiert ... ok +test kontrollfluss_korpusdatei ... ok +test lokaler_handler_hat_vorrang ... ok +test lokaler_handler_verdeckt_modulweiten ... ok +test leere_warteschleife_hat_eine_anweisungsgrenze ... ok +test listenmethoden_indexeigenschaft_und_picture_messung_laufen_in_der_vm ... ok +test listenmethoden_und_indexeigenschaft_laufen_auf_control_arrays ... ok +test modulweiter_handler_faengt_prozedurfehler ... ok +test modelloses_formular_bleibt_nach_programmende_bedienbar ... ok +test mausargumente_kommen_in_zellen_an ... ok +test modulweites_on_error_aus_prozedur ... ok +test objektcode_erzeugt_keine_zusaetzlichen_zustellopcodes ... ok +test modales_show_setzt_nach_unload_fort ... ok +test objektzugriff_laeuft_ueber_objekt_und_eigenschaftsindex ... ok +test ohne_handler_bricht_ab ... ok +test on_error_goto_0_deaktiviert ... ok +test on_local_error_bleibt_prozedurlokal ... ok +test input_s_liest_aus_einer_binaerdatei ... ok +test out_of_data_fehler_4 ... ok +test overflow_bei_zuweisung ... ok +test print_hallo_welt ... ok +test ohne_timer_on_kein_trap ... ok +test on_goto_berechnet ... ok +test alle_mk_cv_paare_verlangen_exakte_bytezeichenbreite ... ok +test printform_schreibt_das_textformular_in_den_druckerkanal ... ok +test resume_next_faehrt_fort ... ok +test resume_ohne_fehler_20 ... ok +test programmversatz_wirkt_auf_alle_zeitfunktionen ... ok +test print_zonen_und_tab ... ok +test rueckfall_auf_utc_laeuft_fehlerfrei ... ok +test resume_wiederholt_anweisung ... ok +test run_gibt_datei_oder_zeile_an_den_runner_weiter ... ok +test restore_mit_label ... ok +test screen_controlpanel_hat_einen_indexierten_laufzeitwert ... ok +test select_case_bereiche ... ok +test sleep_endet_durch_ein_ereignis ... ok +test screen_funktion_ausserhalb_loest_fehler_5_aus ... ok +test screen_anweisung_bildet_grafikmodi_auf_den_zellenpuffer_ab ... ok +test setuevent_loest_den_uevent_trap_aus ... ok +test static_behaelt_werte ... ok +test msgbox_und_inputbox_sind_keine_unsupported_opcodes_mehr ... ok +test stop_liefert_zeile_und_ist_fortsetzbar ... ok +test time_und_now_stimmen_ueberein ... ok +test sondertastenrest_wird_nicht_erneut_getrappt ... ok +test steuerarray_ereignis_stellt_index_voran ... ok +test stringvergleich_und_verkettung ... ok +test datei_und_elternpfadfehler_sind_am_sprachzugang_unterscheidbar ... ok +test timer_zaehlt_ab_lokaler_mitternacht ... ok +test udt_wertsemantik_und_felder ... ok +test width_hebt_die_groesse_an ... ok +test steuerarray_eigenschaften_und_objektparameter_funktionieren ... ok +test timezoneknown_hat_integer_signatur_und_zeigt_aktuellen_status ... ok +test timer_off_im_handler_ueberlebt_das_return ... ok +test zeit_trap_laeuft_und_kehrt_zurueck ... ok +test trap_aus_einer_sub_heraus_kehrt_dorthin_zurueck ... ok +test input_datei_bewahrt_felder_und_unterscheidet_leer_von_fehlend ... ok +test input_datei_alle_lesearten_teilen_utf8_cursor_und_seek ... ok +test unicode_puffergrenzen_und_binaere_records_bleiben_getrennt ... ok +test open_for_isam_endet_nicht_mehr_mit_fehler_73 ... ok + +test result: ok. 114 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s + + Doc-tests tb_export + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_frontend + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_ide + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_runner + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_runtime + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_ui + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests tb_vm + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + ++ cargo test --locked -p tb-cli --test inventar -- --exact abdeckungsstand_wird_ausgewiesen --nocapture + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.02s + Running tests/inventar.rs (target/debug/deps/inventar-4656d211fa731f53) + +running 1 test +Abdeckung: implementiert 795 · offen 0 · Non-Feature 50 · gesamt 845 +Sprache: implementiert 241 · offen 0 · Non-Feature 50 · gesamt 291 +Forms: implementiert 554 · offen 0 · Non-Feature 0 · gesamt 554 +Offene Einträge: keine +test abdeckungsstand_wird_ausgewiesen ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 16 filtered out; finished in 0.00s + ++ cargo fmt --all -- --check ++ cargo clippy --locked --workspace --all-targets -- -D warnings + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s ++ cargo bench --locked -p tb-vm --bench compile --bench vm + Finished `bench` profile [optimized] target(s) in 0.06s + Running benches/compile.rs (target/release/deps/compile-11094da04573b691) +Hardware: macos / aarch64 / Apple M5 Max +Profil: Release / opt-level=3, eigener Harness; cargo bench -p tb-vm --bench compile +Compile-Budget-Benchmark (Release): + Einzelmodul: 508 Zeilen in 0.76 ms (Budget 50 ms) OK + Projekt: 49760 Zeilen in 99 ms (Budget 1000 ms) OK — 335421 Instruktionen + Durchsatz: 501510 Zeilen/s + Cacheänderung: 1 Module, Median 0.76 ms (7 Läufe; Invalidierung + Link), 1 neu / 0 wiederverwendet; Budget 50 ms OK + Cacheänderung: 20 Module, Median 27.60 ms (7 Läufe; Invalidierung + Link), 1 neu / 19 wiederverwendet; Budget 1000 ms OK + Running benches/vm.rs (target/release/deps/vm-861c7a145460d0d5) +VM-Durchsatz-Benchmark (Release): + INTEGER-Schleife (10 Mio): 1193 ms (8.4 Mio Iterationen/s) + DOUBLE-Schleife (5 Mio): 555 ms (9.0 Mio Iterationen/s) + SUB-Aufrufe (1 Mio, BYREF): 139 ms (7.2 Mio Aufrufe/s) + String-Funktionen (200k): 111 ms (1.8 Mio Runden/s) +Phase-6-Grundabnahme bestanden; native Ziel-/Releaseabnahme folgt in Changes 02–07. diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/native-ide.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/native-ide.log new file mode 100644 index 0000000..fe396b8 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/local-acceptance/native-ide.log @@ -0,0 +1,12 @@ + Finished `release` profile [optimized] target(s) in 0.06s + Finished `release` profile [optimized] target(s) in 0.01s + Running `target/release/tb-template /private/var/folders/qv/bccsf2nd15lgm71zrpylrc_80000gn/T/tb-ci-runtime-w6n0ip1v/runtime/aarch64-apple-darwin/tbrt aarch64-apple-darwin` +/private/var/folders/qv/bccsf2nd15lgm71zrpylrc_80000gn/T/tb-ci-runtime-w6n0ip1v/runtime/aarch64-apple-darwin + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.03s + Running unittests src/main.rs (target/debug/deps/tbc-a3652d07eb423d84) + +running 1 test +test ide_acceptance::real_native_ide_exports_and_source_free_cli_library_consumer ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 6 filtered out; finished in 0.68s + diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/openspec.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/openspec.log new file mode 100644 index 0000000..20b1d44 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/openspec.log @@ -0,0 +1,112 @@ +- Validating... +✓ spec/bytecode-kompilat + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/datei-eio + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[8]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ereignissteuerung + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[10]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/forms-dateiformat + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/forms-objektmodell + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/forms-steuerelemente + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-ausfuehrung + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-debugger + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-editor + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-formulardesigner +✓ spec/ide-hilfe +✓ spec/ide-native-exporte +✓ spec/ide-oberflaeche + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[7]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[8]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-phasenabnahme + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/ide-projekte +✓ spec/isam-datenbank + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[7]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/kompat-testkorpus + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[7]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[8]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/konsolen-basisbibliothek + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[8]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[9]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[10]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[11]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/laufzeitfehler +✓ spec/native-executables + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/pcode-bibliotheken + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ change/phase-6-06-gitea-actions-und-releases +✓ change/phase-6-07-dokumentation-und-phasenabnahme +✓ spec/release-kompatibilitaet +✓ spec/sprach-frontend + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[7]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[10]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[11]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[13]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/sprachinventar + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[2]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/terminal-plattformmatrix + ℹ [INFO] requirements[1]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/textbildschirm + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[4]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[6]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[8]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[9]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[10]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/vm-ausfuehrung + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[3]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[5]: Requirement text is very long (>500 characters). Consider breaking it down. + ℹ [INFO] requirements[7]: Requirement text is very long (>500 characters). Consider breaking it down. +✓ spec/vm-fehlerbehandlung + ℹ [INFO] requirements[0]: Requirement text is very long (>500 characters). Consider breaking it down. +Totals: 30 passed, 0 failed (30 items) diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/package-sha256.json b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/package-sha256.json new file mode 100644 index 0000000..6c85323 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/package-sha256.json @@ -0,0 +1,6 @@ +{ + "terminalbasic-0.1.0-linux-amd64.tar.gz": "2ced064df0d1c8b041f23df1a668787d22933b2f6be646e01f73061cc20a4e04", + "terminalbasic-0.1.0-linux-arm64.tar.gz": "e1eff42146202fe4694b8812a17acfc9337a454a27c0ef36d53a3fc776088b81", + "terminalbasic-0.1.0-macos-arm64.tar.gz": "369882d9962f0264f41a7dfc0e352acb826c43d84a3c8babd028636a24aeaf4d", + "terminalbasic-0.1.0-windows-amd64.7z": "8fb79b0e34f2a496a93e90f87c70d9bff2d5b38b77087a123518491d0964e092" +} diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/release-tests.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/release-tests.log new file mode 100644 index 0000000..243b332 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/release-tests.log @@ -0,0 +1,5 @@ +..... +---------------------------------------------------------------------- +Ran 5 tests in 0.017s + +OK diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/unix-package.log b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/unix-package.log new file mode 100644 index 0000000..5c8beab --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/unix-package.log @@ -0,0 +1,30 @@ ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tb aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tbc aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/aarch64-unknown-linux-gnu/release/tbrt aarch64-unknown-linux-gnu ++ /work/target/release/tb-template /tmp/tb-pack-o13p5pm9/runtimes/aarch64-unknown-linux-gnu/tbrt aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-g7jby_v7/tb aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-g7jby_v7/tbc aarch64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-g7jby_v7/runtimes/aarch64-unknown-linux-gnu/tbrt aarch64-unknown-linux-gnu +/work/dist-final/terminalbasic-0.1.0-linux-arm64.tar.gz ++ /tmp/tb-unpacked-akoqbup6/tb --help ++ /tmp/tb-unpacked-akoqbup6/tbc build /tmp/tb-unpacked-akoqbup6/hello.bas --exe --target aarch64-unknown-linux-gnu -o /tmp/tb-unpacked-akoqbup6/hello +/tmp/tb-unpacked-akoqbup6/hello ++ /usr/bin/python3 /work/tests/support/native-abnahme.py --bin-dir /tmp/tb-unpacked-akoqbup6 --target aarch64-unknown-linux-gnu ++ /usr/bin/python3 /work/tests/support/library-abnahme.py --bin-dir /tmp/tb-unpacked-akoqbup6 ++ /usr/bin/python3 /work/tests/support/ide-execution-pty.py --binary /tmp/tb-unpacked-akoqbup6/tb ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tb x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tbc x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /work/target/x86_64-unknown-linux-gnu/release/tbrt x86_64-unknown-linux-gnu ++ /work/target/release/tb-template /tmp/tb-pack-lrb4e1pp/runtimes/x86_64-unknown-linux-gnu/tbrt x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-1agxs6xy/tb x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-1agxs6xy/tbc x86_64-unknown-linux-gnu ++ /work/target/release/tb-template --inspect /tmp/tb-package-1agxs6xy/runtimes/x86_64-unknown-linux-gnu/tbrt x86_64-unknown-linux-gnu +/work/dist-final/terminalbasic-0.1.0-linux-amd64.tar.gz ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tb aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tbc aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /work/target/aarch64-apple-darwin/release/tbrt aarch64-apple-darwin ++ /work/target/release/tb-template /tmp/tb-pack-dlq0c_7h/runtimes/aarch64-apple-darwin/tbrt aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-w9maj5ky/tb aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-w9maj5ky/tbc aarch64-apple-darwin ++ /work/target/release/tb-template --inspect /tmp/tb-package-w9maj5ky/runtimes/aarch64-apple-darwin/tbrt aarch64-apple-darwin +/work/dist-final/terminalbasic-0.1.0-macos-arm64.tar.gz diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/working-tree.patch b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/working-tree.patch new file mode 100644 index 0000000..a741e51 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/evidence/working-tree.patch @@ -0,0 +1,161 @@ +diff --git a/.gitignore b/.gitignore +index b7141ea..15c6f97 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -1,3 +1,8 @@ + /target + **/*.rs.bk + *.pdb ++/dist ++/acceptance ++/artifacts ++/packages ++**/__pycache__ +diff --git a/crates/tb-export/src/bin/tb-template.rs b/crates/tb-export/src/bin/tb-template.rs +index 7776b1a..c1ed101 100644 +--- a/crates/tb-export/src/bin/tb-template.rs ++++ b/crates/tb-export/src/bin/tb-template.rs +@@ -1,10 +1,23 @@ + //! Builder-Hilfe: geprüfte Metadaten für eine frisch gebaute Runtime schreiben. + fn main() -> anyhow::Result<()> { +- let args: Vec<_> = std::env::args().skip(1).collect(); ++ let mut args: Vec<_> = std::env::args().skip(1).collect(); ++ let inspect = args.first().is_some_and(|s| s == "--inspect"); ++ if inspect { ++ args.remove(0); ++ } + anyhow::ensure!( + args.len() == 2, +- "Aufruf: tb-template " ++ "Aufruf: tb-template [--inspect] " + ); ++ if inspect { ++ let found = tb_export::native_target(&std::fs::read(&args[0])?)?; ++ anyhow::ensure!( ++ found == tb_export::Target::parse(&args[1])?, ++ "Executable hat falsches Ziel" ++ ); ++ println!("{}", found.triple()); ++ return Ok(()); ++ } + tb_export::prepare_template( + std::path::Path::new(&args[0]), + tb_export::Target::parse(&args[1])?, +diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md b/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md +index 9ed6dd3..8134698 100644 +--- a/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md ++++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/design.md +@@ -12,7 +12,7 @@ Origin ist `https://git.rfc1437.de/hugo/TerminalBasic.git`; die read-only Versio + + 1. `.gitea/workflows/` nutzt den vorhandenen Linux-arm64-Runner für alle vier Build-/Paketziele. Vorhandene Workflowmuster der anderen Origin-Projekte wiederverwenden: cargo-zigbuild für Linux amd64 und macOS arm64, cargo-xwin für Windows amd64/MSVC; Linux arm64 nativ oder mit derselben festgelegten Linux-Zielbaseline. Container/Tools und benötigte SDKs/Sysroots reproduzierbar pinnen; konkrete Rust-/OS-/glibc-Versionen mit TerminalBasic prüfen. Das Runnerlabel `linux-arm64` bei Anbindung bestätigen. Vier native Buildrunner sind nicht erforderlich. `build-runtime.py` erzeugt Vorlagenmetadaten mit dem Hostwerkzeug für das jeweilige Target; fremde Executables werden auf dem Buildhost nicht nativ ausgeführt. + 2. Wiederverwendbare Repository-Skripte erledigen Build, Tests, Paketierung und Prüfung auch lokal. Source-Checkout vom Gitea-Origin, alle zusätzlichen Actions nur über explizite Gitea-URLs und feste Revisionen, soweit überhaupt nötig; keine implizite fremde Action-Auflösung. Rust und benötigte Systemwerkzeuge versioniert bereitstellen. Server-/Runner-Kompatibilität praktisch prüfen, statt lediglich YAML zu validieren. +-3. Matrixprodukte: `terminalbasic--windows-amd64.7z`, `terminalbasic--macos-arm64.tar.gz`, `terminalbasic--linux-amd64.tar.gz`, `terminalbasic--linux-arm64.tar.gz`. Windows enthält `tb.exe`/`tbc.exe`/`tbrt.exe`, übrige `tb`/`tbc`/`tbrt`; tbrt ist die native Exportvorlage, dazu deren Metadaten, Lizenz, Kurzinstallation. Archive dürfen keine Buildverzeichnis-/Quellbaumabhängigkeiten haben. Exportierte Anwenderprogramme bleiben normale native Einzelartefakte; die Archivformate betreffen die Distribution. ++3. Matrixprodukte: `terminalbasic--windows-amd64.7z`, `terminalbasic--macos-arm64.tar.gz`, `terminalbasic--linux-amd64.tar.gz`, `terminalbasic--linux-arm64.tar.gz`. Windows enthält `tb.exe`/`tbc.exe`/`tbrt.exe`, übrige `tb`/`tbc`/`tbrt`; tbrt ist die native Exportvorlage unter `runtimes//`, dazu deren Metadaten, Lizenz, Kurzinstallation. Das vorhandene CLI-/IDE-Suchschema bleibt erhalten. Archive dürfen keine Buildverzeichnis-/Quellbaumabhängigkeiten haben. Exportierte Anwenderprogramme bleiben normale native Einzelartefakte; die Archivformate betreffen die Distribution. + 4. Der Linux-Buildhost erzeugt/prüft Windows-Archive mit 7-Zip und Unix-Archive mit tar+gzip unter Erhalt der Executable-Bits. Inhalts-/Formatprüfungen laufen dort; tatsächliche Start-/Exportprüfungen verwenden neu entpackte Pakete auf passenden Zielsystemen aus 05, automatisiert oder dokumentiert manuell. Externe Nachweise müssen an Revision und exakte Paketprüfsumme gebunden und vor Freigabe geprüft sein. Ein gemeinsames TBL-Testartefakt wird einmal erzeugt und mit nachgewiesen identischen Bytes auf allen vier Zielsystemen verwendet. Separate BASIC-Verbraucher werden mit den entpackten TB-Tools verknüpft, als TBC ausgeführt und mit tbrt als EXE exportiert. Library-Quellen sind dabei nicht verfügbar. Erzeugung/Linken werden in einer Umgebung ohne erreichbaren C-/Rust-Compiler oder nativen Linker geprüft; Systemhilfen zur EXE-Finalisierung dürfen verfügbar bleiben. Fertige EXEs laufen anschließend ohne externe TBL/TBC oder TB-Installation. + 5. `cargo test --locked --workspace`, Clippy und Formatprüfung zentral auf dem Linux-arm64-Host; zielabhängige Rust-Testprogramme bei Bedarf cross-kompilieren und auf passenden Prüfsystemen ausführen. Native Tests aus 02/03/04 und automatisierbare Plattformtests aus 05 auf ihren tatsächlichen Zielen ausführen. Buildstatus und Ausführungsnachweise getrennt ausweisen; macOS-EXE-Finalisierung mit codesign erfolgt auf macOS. Den fixierten Fremdprogrammbestand ausdrücklich im erforderlichen Abnahmelauf bereitstellen. Compile-/VM-Messungen auf dokumentiertem Referenzrunner statt instabiler Debug-Zeitlimits in allen Jobs. + 6. Gitea-Release erst nach allen Pflichtjobs, zugeordneten echten Zielnachweisen und Vollständigkeits-/Prüfsummenprüfung freigeben. Upload zunächst zu einem als Entwurf erkennbaren Release oder gleichwertigem nicht freigegebenen Staging; anschließend atomare Freigabe im Rahmen der verfügbaren API. PR-Jobs ohne Veröffentlichungsrechte und ohne Release-Secrets; fremder PR-Code darf nicht mit solchen Rechten auf persönlichen Runnern laufen. Zugangswerte werden als Gitea-Secrets konfiguriert, nicht committed. Tests erzeugen keine öffentlichen Testreleases. +@@ -28,3 +28,20 @@ Origin ist `https://git.rfc1437.de/hugo/TerminalBasic.git`; die read-only Versio + ## Migration Plan + + Lokale Skripte zuerst lauffähig machen, dann Gitea-Runner und Workflows anbinden. PR-/Push-Lauf ohne Veröffentlichung prüfen; kontrollierter Tag-/Release-Lauf nach erfolgreicher Matrix. Bisherige lokale Cargo-Nutzung erhalten. Rollback über vorheriges vollständiges Release und Rücknahme der Workflowänderung; keine Server-/Runnerinstallation durch bloße Proposal-Erstellung. ++ ++## Konkretisierung während der Umsetzung ++ ++- Rust 1.97.1, vorhandene Cross-Images per Digest, 7-Zip 25.01 per SHA-256. ++ SDK-/CRT-Versionen und ein Hash ihrer exakten Header-/Library-Bytes sind ++ für Windows fixiert; macOS-SDK/Zig stammen aus dem gepinnten Image. ++- `tb-template --inspect` nutzt den vorhandenen PE/ELF/Mach-O-Parser auch ++ für tb/tbc. Build und Paketprüfung laufen auf dem Host ohne fremde Programme ++ auszuführen. Die Anwenderpakete benötigen tb-template nicht. ++- Taglauf erzeugt erst nach Build/Grundabnahme einen überprüften Entwurf. ++ Originalpakete werden auf separaten Systemen geprüft. Ein manueller Workflow ++ auf main bindet deren Nachweise aus einem Origin-Commit an Tag, Revision und ++ Paket-SHA-256 und gibt erst dann denselben Entwurf frei; kein erneuter Bau. ++- Die Benutzerentscheidung aus 05, Windows-Ausführung vorerst offen zu lassen, ++ bleibt erhalten. Sie macht Windows-Builds zulässig, aber keinen Release mit ++ fehlender Windows-Abnahme erfolgreich. Fehlende Nachweise werden nicht auf ++ Basis der gemeinsamen ANSI-Technik von macOS/Linux pauschal abgehakt. +diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md b/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md +index 3f1d0c2..a226e36 100644 +--- a/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md ++++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md +@@ -1,19 +1,27 @@ + ## 1. Gitea und Runner + + - [ ] 1.1 Vorhandenen Linux-arm64-Gitea-Runner und tatsächliches Label bestätigen; Cross-Buildumgebungen mit cargo-zigbuild, cargo-xwin und benötigten SDKs/Sysroots reproduzierbar festlegen. Ein Gitea-Prüfjob muss den Buildhost nachweisen; separate echte Prüfsysteme aus 05 zuordnen, ohne vier native Buildrunner vorauszusetzen. +-- [ ] 1.2 Repositorylokale Build-/Testaufrufe und feste Toolchain-/Systemvoraussetzungen bereitstellen; alle vier Ziele müssen auf Linux arm64 mit --locked baubar sein. Zentrale Workspace-Regressionen und getrennte Aufrufe für echte Zielprüfungen bereitstellen; fremde Executables nicht als nativ auf dem Buildhost getestet ausweisen. ++- [x] 1.2 Repositorylokale Build-/Testaufrufe und feste Toolchain-/Systemvoraussetzungen bereitstellen; alle vier Ziele müssen auf Linux arm64 mit --locked baubar sein. Zentrale Workspace-Regressionen und getrennte Aufrufe für echte Zielprüfungen bereitstellen; fremde Executables nicht als nativ auf dem Buildhost getestet ausweisen. + - [ ] 1.3 Push-/PR-Workflow unter .gitea/workflows anbinden; ein tatsächlicher Origin-Lauf muss vier Zielergebnisse und Fehlerstatus liefern, ohne Release-Secrets im PR-Pfad. + + ## 2. Artefakte und Pakete + + - [ ] 2.1 IDE, CLI und native `tbrt`-Exportvorlage je Ziel in Gitea Actions bauen; Format-/Architektur-/Versionsprüfungen müssen Windows amd64, macOS arm64 und beide Linux-Architekturen eindeutig bestätigen. +-- [ ] 2.2 Windows-Paket als .7z und macOS-/Linux-Pakete als .tar.gz erzeugen; Archivtests müssen Dateinamen, Paketinhalt, Executable-Rechte und notwendige Begleitdateien prüfen. ++- [x] 2.2 Windows-Paket als .7z und macOS-/Linux-Pakete als .tar.gz erzeugen; Archivtests müssen Dateinamen, Paketinhalt, Executable-Rechte und notwendige Begleitdateien prüfen. + - [ ] 2.3 Jedes fertige Paket auf dem tatsächlichen Ziel neu entpacken und die enthaltenen Programme starten; automatisierte oder dokumentiert manuelle Nachweise aus separaten Prüfsystemen an Revision und Paketprüfsumme binden; `tbc link` und EXE-/TBL-Beispiele müssen mit separaten BASIC-Verbrauchern ohne Library-Quellen/Entwicklungscheckout sowie ohne erreichbaren C-/Rust-Compiler oder nativen Linker funktionieren. +-- [ ] 2.4 Einmal erzeugte TBL-Probe mit identischen Bytes an alle vier Zielprüfungen verteilen sowie Artefaktmanifest und Prüfsummen erzeugen; absichtlich beschädigte oder vertauschte Zielartefakte müssen die Prüfung scheitern lassen. ++- [x] 2.4 Einmal erzeugte TBL-Probe mit identischen Bytes an alle vier Zielprüfungen verteilen sowie Artefaktmanifest und Prüfsummen erzeugen; absichtlich beschädigte oder vertauschte Zielartefakte müssen die Prüfung scheitern lassen. + + ## 3. Releasepfad + + - [ ] 3.1 Taggebundenen Gitea-Releasepfad mit vollständiger Pflichtasset-Liste und getrennten Rechten einrichten; fehlgeschlagene/fehlende Zielbuilds oder zugeordnete echte Paket-/Zielprüfungen müssen die Freigabe verhindern. +-- [ ] 3.2 Upload zunächst als nicht freigegebenen Stand prüfen und erst vollständig freigeben; ein simulierter fehlender Upload darf keinen vollständigen bestehenden Release überschreiben. +-- [ ] 3.3 Fremdprogramm-, Inventar-, native und automatisierte Plattformnachweise sowie Referenzbenchmarks in den erforderlichen Abnahmelauf integrieren; ignorierte Pflichtfälle müssen als fehlend sichtbar bleiben. ++- [x] 3.2 Upload zunächst als nicht freigegebenen Stand prüfen und erst vollständig freigeben; ein simulierter fehlender Upload darf keinen vollständigen bestehenden Release überschreiben. ++- [x] 3.3 Fremdprogramm-, Inventar-, native und automatisierte Plattformnachweise sowie Referenzbenchmarks in den erforderlichen Abnahmelauf integrieren; ignorierte Pflichtfälle müssen als fehlend sichtbar bleiben. + - [ ] 3.4 Einen tatsächlichen vollständigen Gitea-Lauf mit vier Paketartefakten nachweisen; Run-/Commit-/Buildhost-/Targetdaten und paketprüfsummengebundene entpackte Prüfergebnisse an 07 übergeben, bevor der Change als fertig gilt. ++ ++Stand 07.09.2026: Repository-Implementierung und lokale Prüfungen vorhanden. ++Alle vier Ziele wurden in den fixierten Containern auf Linux arm64 gebaut; ++Linux-arm64- und cross-kompilierte macOS-Pakete bestehen echte entpackte ++Automatikprüfungen. Das ist noch kein Actions-Lauf. 1.1/1.3/2.1/3.4 bleiben ++wegen des defekten gemeinsamen Runners offen; 2.3 wegen Windows/Linux-amd64 ++und den restlichen visuellen Zielnachweisen. 3.1 bleibt bis zur Einrichtung ++des Releasezugangs und tatsächlichen Rechteprüfung offen. Details: verification.md. +diff --git a/tests/support/library-abnahme.py b/tests/support/library-abnahme.py +index c596219..003e064 100644 +--- a/tests/support/library-abnahme.py ++++ b/tests/support/library-abnahme.py +@@ -63,8 +63,15 @@ def main(): + library = root / 'library.tbl' + shutil.copyfile(args.library, library) + template = root / ('runtime' + suffix) +- shutil.copy2(binaries / ('tbrt' + suffix), template) +- run([template_tool, template, target], root, env) ++ runtime = binaries / ('tbrt' + suffix) ++ if not runtime.is_file(): ++ runtime = binaries / 'runtimes' / target / ('tbrt' + suffix) ++ shutil.copy2(runtime, template) ++ metadata = Path(str(runtime) + '.meta') ++ if metadata.is_file(): ++ shutil.copyfile(metadata, Path(str(template) + '.meta')) ++ else: ++ run([template_tool, template, target], root, env) + source = root / 'consumer.bas' + source.write_text(SOURCE, encoding='utf-8') + linked = root / 'consumer.tbc' +diff --git a/tests/support/native-abnahme.py b/tests/support/native-abnahme.py +index 78f4c2a..837d868 100644 +--- a/tests/support/native-abnahme.py ++++ b/tests/support/native-abnahme.py +@@ -76,13 +76,19 @@ def main(): + suffix = '.exe' if args.target == 'x86_64-pc-windows-msvc' else '' + tbc = binaries / ('tbc' + suffix) + rt = binaries / ('tbrt' + suffix) ++ if not rt.is_file(): ++ rt = binaries / 'runtimes' / args.target / ('tbrt' + suffix) + prepare = binaries / ('tb-template' + suffix) + env = dict(os.environ, PATH='') # weder Cargo noch tbc/tbrt über PATH auflösbar + with tempfile.TemporaryDirectory(prefix='tb-native-') as work: + root = Path(work) + template = root / ('runtime' + suffix) + shutil.copy2(rt, template) +- must(run([prepare, template, args.target], root)) ++ metadata = Path(str(rt) + '.meta') ++ if metadata.is_file(): ++ shutil.copyfile(metadata, Path(str(template) + '.meta')) ++ else: ++ must(run([prepare, template, args.target], root)) + empty = run([template], root, env=env) + assert empty.returncode == 1 and b'Nutzlast' in empty.stderr, empty + cases = { diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md b/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md index 3f1d0c2..a226e36 100644 --- a/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/tasks.md @@ -1,19 +1,27 @@ ## 1. Gitea und Runner - [ ] 1.1 Vorhandenen Linux-arm64-Gitea-Runner und tatsächliches Label bestätigen; Cross-Buildumgebungen mit cargo-zigbuild, cargo-xwin und benötigten SDKs/Sysroots reproduzierbar festlegen. Ein Gitea-Prüfjob muss den Buildhost nachweisen; separate echte Prüfsysteme aus 05 zuordnen, ohne vier native Buildrunner vorauszusetzen. -- [ ] 1.2 Repositorylokale Build-/Testaufrufe und feste Toolchain-/Systemvoraussetzungen bereitstellen; alle vier Ziele müssen auf Linux arm64 mit --locked baubar sein. Zentrale Workspace-Regressionen und getrennte Aufrufe für echte Zielprüfungen bereitstellen; fremde Executables nicht als nativ auf dem Buildhost getestet ausweisen. +- [x] 1.2 Repositorylokale Build-/Testaufrufe und feste Toolchain-/Systemvoraussetzungen bereitstellen; alle vier Ziele müssen auf Linux arm64 mit --locked baubar sein. Zentrale Workspace-Regressionen und getrennte Aufrufe für echte Zielprüfungen bereitstellen; fremde Executables nicht als nativ auf dem Buildhost getestet ausweisen. - [ ] 1.3 Push-/PR-Workflow unter .gitea/workflows anbinden; ein tatsächlicher Origin-Lauf muss vier Zielergebnisse und Fehlerstatus liefern, ohne Release-Secrets im PR-Pfad. ## 2. Artefakte und Pakete - [ ] 2.1 IDE, CLI und native `tbrt`-Exportvorlage je Ziel in Gitea Actions bauen; Format-/Architektur-/Versionsprüfungen müssen Windows amd64, macOS arm64 und beide Linux-Architekturen eindeutig bestätigen. -- [ ] 2.2 Windows-Paket als .7z und macOS-/Linux-Pakete als .tar.gz erzeugen; Archivtests müssen Dateinamen, Paketinhalt, Executable-Rechte und notwendige Begleitdateien prüfen. +- [x] 2.2 Windows-Paket als .7z und macOS-/Linux-Pakete als .tar.gz erzeugen; Archivtests müssen Dateinamen, Paketinhalt, Executable-Rechte und notwendige Begleitdateien prüfen. - [ ] 2.3 Jedes fertige Paket auf dem tatsächlichen Ziel neu entpacken und die enthaltenen Programme starten; automatisierte oder dokumentiert manuelle Nachweise aus separaten Prüfsystemen an Revision und Paketprüfsumme binden; `tbc link` und EXE-/TBL-Beispiele müssen mit separaten BASIC-Verbrauchern ohne Library-Quellen/Entwicklungscheckout sowie ohne erreichbaren C-/Rust-Compiler oder nativen Linker funktionieren. -- [ ] 2.4 Einmal erzeugte TBL-Probe mit identischen Bytes an alle vier Zielprüfungen verteilen sowie Artefaktmanifest und Prüfsummen erzeugen; absichtlich beschädigte oder vertauschte Zielartefakte müssen die Prüfung scheitern lassen. +- [x] 2.4 Einmal erzeugte TBL-Probe mit identischen Bytes an alle vier Zielprüfungen verteilen sowie Artefaktmanifest und Prüfsummen erzeugen; absichtlich beschädigte oder vertauschte Zielartefakte müssen die Prüfung scheitern lassen. ## 3. Releasepfad - [ ] 3.1 Taggebundenen Gitea-Releasepfad mit vollständiger Pflichtasset-Liste und getrennten Rechten einrichten; fehlgeschlagene/fehlende Zielbuilds oder zugeordnete echte Paket-/Zielprüfungen müssen die Freigabe verhindern. -- [ ] 3.2 Upload zunächst als nicht freigegebenen Stand prüfen und erst vollständig freigeben; ein simulierter fehlender Upload darf keinen vollständigen bestehenden Release überschreiben. -- [ ] 3.3 Fremdprogramm-, Inventar-, native und automatisierte Plattformnachweise sowie Referenzbenchmarks in den erforderlichen Abnahmelauf integrieren; ignorierte Pflichtfälle müssen als fehlend sichtbar bleiben. +- [x] 3.2 Upload zunächst als nicht freigegebenen Stand prüfen und erst vollständig freigeben; ein simulierter fehlender Upload darf keinen vollständigen bestehenden Release überschreiben. +- [x] 3.3 Fremdprogramm-, Inventar-, native und automatisierte Plattformnachweise sowie Referenzbenchmarks in den erforderlichen Abnahmelauf integrieren; ignorierte Pflichtfälle müssen als fehlend sichtbar bleiben. - [ ] 3.4 Einen tatsächlichen vollständigen Gitea-Lauf mit vier Paketartefakten nachweisen; Run-/Commit-/Buildhost-/Targetdaten und paketprüfsummengebundene entpackte Prüfergebnisse an 07 übergeben, bevor der Change als fertig gilt. + +Stand 07.09.2026: Repository-Implementierung und lokale Prüfungen vorhanden. +Alle vier Ziele wurden in den fixierten Containern auf Linux arm64 gebaut; +Linux-arm64- und cross-kompilierte macOS-Pakete bestehen echte entpackte +Automatikprüfungen. Das ist noch kein Actions-Lauf. 1.1/1.3/2.1/3.4 bleiben +wegen des defekten gemeinsamen Runners offen; 2.3 wegen Windows/Linux-amd64 +und den restlichen visuellen Zielnachweisen. 3.1 bleibt bis zur Einrichtung +des Releasezugangs und tatsächlichen Rechteprüfung offen. Details: verification.md. diff --git a/openspec/changes/phase-6-06-gitea-actions-und-releases/verification.md b/openspec/changes/phase-6-06-gitea-actions-und-releases/verification.md new file mode 100644 index 0000000..f702a64 --- /dev/null +++ b/openspec/changes/phase-6-06-gitea-actions-und-releases/verification.md @@ -0,0 +1,111 @@ +# Verifizierung: phase-6-06-gitea-actions-und-releases + +Stand 07.09.2026. Basis: `796564795a6607651c366c6b0de74560af55e71a` +mit dem dokumentierten Change-06-Diff. Change 05 wurde zuvor synchronisiert, +auf Benutzeranweisung archiviert und dieser Commit auf Origin bestätigt. + +## Ergebnis + +| Dimension | Stand | +|---|---| +| Vollständigkeit | 5/11 Aufgaben abgeschlossen; sechs Aufgaben mit echten Origin-/Ziel-/Rechtenachweisen offen | +| Korrektheit | Vier echte Cross-/Native-Builds auf Linux arm64; native Paketprüfungen auf Linux arm64 und macOS arm64 bestanden; lokale Pflichtabnahme und negative Paket-/Releaseprüfungen bestanden | +| Kohärenz | Bestehende Exportvalidierung, Vorlagenpfade, TBL-/Native-/PTY-Prüfungen wiederverwendet; keine neue Produktabhängigkeit | + +Keine aktuell bekannte unbehobene lokale Codeabweichung. Der Change ist +wegen der unten benannten fehlenden externen Nachweise **nicht vollständig +verifiziert oder archivierungsbereit**. Vier lokal orchestrierte Container- +builds auf dem Gitea-Host sind keine vier erfolgreichen Actions-Jobs. + +## Umsetzung und Szenarioabdeckung + +- `.gitea/workflows/build.yml`: Push/interner PR, vier Targets auf + `linux-arm64`, gepinnte Images/Action-Commits, getrennte Grundabnahme und + Paketartefakte. Fremde PRs laufen nicht auf dem persönlichen Runner. +- `.gitea/scripts/build.py`, `bootstrap.sh`, `rust-toolchain.toml`: feste + Toolchain, SDK-/CRT-Versionen und Inhaltsprüfung, statische Windows-CRT, + glibc-Buildbaseline 2.28, macOS-Deployment 11.0. Das sind Buildvorgaben, + keine nachgewiesenen minimalen OS-Versionen. +- `distribution.py`: richtige `.7z`-/`.tar.gz`-Formate, vollständige Inhalte, + 0755 für Unix-Executables, Dateiprüfsummen, Versions-/Target-/Revision- + Manifest. Entpacken lehnt fremde Pfade, Links und unvollständige Archive ab. + `tb-template --inspect` verwendet den vorhandenen nativen Formatparser. +- `target-check`: Programme aus frisch entpackten Paketen starten; EXE-Export + ohne expliziten Vorlagenpfad, native Parität, identische portable.tbl, + quellfreie Verbraucher, leerer PATH ohne Compiler/Linker, Unix-PTY; Windows + verlangt zusätzlich das explizite Konsolentestexecutable. Manuelle + Emulatorfolgen bleiben getrennt und revisions-/paketgebunden. +- `release.py`, `publish.py`, `publish.yml`: Tag-/Commitbindung, vollständige + Pflichtassets, Entwurfsstatus, Zurücklesen mit Bytevergleich, keine Ersetzung + existierender abweichender Assets oder veröffentlichter Releases. Fehlende, + falsche oder unvollständige Ziel-/Terminal-/Grundnachweise verhindern den + letzten `draft=false`-Aufruf. Nachweise stammen aus einem Origin-Commit. +- `acceptance.py`: bestehende Fremdprogramm-/Inventar-/Workspace-/Clippy-/ + Format-/Compile-/VM-Prüfung sowie explizite native IDE-Abnahme. Fehlende + Konfiguration, ignorierte Pflichtläufe und Fehler werden nicht grün. +- `docs/distribution.md`, `INSTALL.txt`: Aufrufe, Paketlayout, Rechte, + Systemgrenzen, manuelle Nachweisform und Freigabefolge. + +## Gefundene und behobene Befunde + +1. Die neuen Paketprüfungen verwendeten zunächst `tbc --help`, obwohl die + CLI diesen Aufruf nicht unterstützt. Prüfung/Installation verwenden jetzt + echte Compiler-/Exportbefehle; keine zusätzliche CLI-Funktion nötig. +2. Ein flaches tbrt neben tb/tbc erfüllte die bestehenden automatischen + Suchpfade nicht. Archive enthalten nun `runtimes//tbrt[.exe]` + samt Metadaten. Der ausdrückliche Test ohne `--template` besteht. +3. Alte Abnahmeskripte setzten das Entwicklerwerkzeug tb-template voraus. + Sie verwenden vorhandene Paketmetadaten; der bisherige Entwicklerpfad + bleibt für nicht paketierte Builds verfügbar. +4. Die native IDE-Pflichtprobe erhielt zunächst den falschen Runtime-Basispfad. + `acceptance.py` legt die Vorlage im geforderten Target-Unterverzeichnis ab; + der vollständige Abnahmelauf besteht nach der Korrektur. +5. Der vorhandene cargo-xwin-Stand akzeptiert den VS-Kanal nur numerisch; + CRT-Auswahl benutzt die Manifest-ID `14.44.17.14`, nicht die Dateiversion. + Mit Kanal 17 und den tatsächlichen IDs bestehen Build und .7z-Prüfung. + Zusätzlich verhindert der SDK-Inhaltspin eine stille Änderung unter + unveränderten Versionsbezeichnungen. + +## Nachweise + +- Vier Targets auf dem tatsächlichen Linux-aarch64-Gitea-Host gebaut; + PE/amd64/Console, Mach-O/arm64 und beide ELF-Maschinen geprüft. +- Echte entpackte Linux-arm64-Paketprüfung auf Linux 6.8.0-139/glibc 2.41. +- Das auf Linux cross-kompilierte macOS-Paket auf macOS 26.6.2/arm64 gestartet: + Standard-Vorlagenpfad, native Fälle, TBL, IDE-Shell/Abbruch/Wiederherstellung + bestanden. Die Programme wurden dabei nicht lokal erneut gebaut. +- Fünf automatisierte Paket-/Release-Regressionen: vollständiger Satz, + fehlende/falsche Nachweise, Korruption, falsche Revision, schmutzige Quellen, + Archiv-Traversierung, fehlender Upload, sichere Wiederholung, Schutz bereits + veröffentlichter Releases. Keine öffentlichen Testreleases erzeugt. +- Zusätzlich echte negative Artefaktproben: Mach-O als Linux deklariert und + verändertes Executable innerhalb eines Archivs werden abgelehnt. +- Lokaler vollständiger Pflichtlauf mit fixiertem Fremdbestand einschließlich + Benchmarks und expliziter nativer IDE-Probe bestanden. Exporttests, Clippy, + Format, YAML-Parsing und OpenSpec-Validierung bestanden. + +Die gebauten Testpakete tragen den uncommitteten Diffstand im Manifest und +sind absichtlich nicht releasefähig. Lokale Belege werden unter `evidence/` +aufbewahrt; Paketprüfsummen und tatsächliche Hostdaten stehen in den Berichten. + +## Offene externe Befunde + +- **1.1/1.3/2.1/3.4:** Gitea 1.25.4, Actions am Repository aktiviert, + registrierter Runner `gitea-arm64-01`, Label `linux-arm64` bestätigt. + Der Runner ist in einer Neustartschleife: `rootlesskit ... /proc/self/exe: + operation not permitted`. Eine Entscheidung zur Reparatur des gemeinsamen + Runners wurde angefragt. Keine Docker-/AppArmor-Konfiguration verändert. + Ein echter erfolgreicher Actions-Matrixlauf und dessen Rechteverhalten fehlen. +- **2.3:** Windows-Ausführung bleibt entsprechend Benutzerentscheidung offen; + Linux amd64 und die vollständigen manuellen Emulatorfolgen sind ebenfalls + nicht belegt. Cross-Build, lokale Mocktests und gemeinsame ANSI-Technik + ersetzen diese Prüfungen nicht. +- **3.1:** Der getrennte Releasezugang `TB_RELEASE_TOKEN` ist noch nicht + eingerichtet/verifiziert. Es wurde kein persönlicher Git-Zugang als + dauerhaftes Release-Secret übernommen. Die Referenzvariable für den + vorhandenen fixierten Fremdbestand wurde am Repository eingerichtet. + +Diese Befunde lassen sich nicht durch Änderungen an Paketcode oder durch +Abhaken von Aufgaben schließen. Nach Runner-Reparatur den Origin-Lauf ausführen, +zugehörige Paket-/Zielnachweise ergänzen und kontrollierte Entwurfs-/Rechte- +prüfung durchführen. Bis dahin keine Freigabe und keine Behauptung „0 Befunde“. diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..3caff2a --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.97.1" +profile = "minimal" +components = ["clippy", "rustfmt"] diff --git a/tests/support/library-abnahme.py b/tests/support/library-abnahme.py index c596219..003e064 100644 --- a/tests/support/library-abnahme.py +++ b/tests/support/library-abnahme.py @@ -63,8 +63,15 @@ def main(): library = root / 'library.tbl' shutil.copyfile(args.library, library) template = root / ('runtime' + suffix) - shutil.copy2(binaries / ('tbrt' + suffix), template) - run([template_tool, template, target], root, env) + runtime = binaries / ('tbrt' + suffix) + if not runtime.is_file(): + runtime = binaries / 'runtimes' / target / ('tbrt' + suffix) + shutil.copy2(runtime, template) + metadata = Path(str(runtime) + '.meta') + if metadata.is_file(): + shutil.copyfile(metadata, Path(str(template) + '.meta')) + else: + run([template_tool, template, target], root, env) source = root / 'consumer.bas' source.write_text(SOURCE, encoding='utf-8') linked = root / 'consumer.tbc' diff --git a/tests/support/native-abnahme.py b/tests/support/native-abnahme.py index 78f4c2a..837d868 100644 --- a/tests/support/native-abnahme.py +++ b/tests/support/native-abnahme.py @@ -76,13 +76,19 @@ def main(): suffix = '.exe' if args.target == 'x86_64-pc-windows-msvc' else '' tbc = binaries / ('tbc' + suffix) rt = binaries / ('tbrt' + suffix) + if not rt.is_file(): + rt = binaries / 'runtimes' / args.target / ('tbrt' + suffix) prepare = binaries / ('tb-template' + suffix) env = dict(os.environ, PATH='') # weder Cargo noch tbc/tbrt über PATH auflösbar with tempfile.TemporaryDirectory(prefix='tb-native-') as work: root = Path(work) template = root / ('runtime' + suffix) shutil.copy2(rt, template) - must(run([prepare, template, args.target], root)) + metadata = Path(str(rt) + '.meta') + if metadata.is_file(): + shutil.copyfile(metadata, Path(str(template) + '.meta')) + else: + must(run([prepare, template, args.target], root)) empty = run([template], root, env=env) assert empty.returncode == 1 and b'Nutzlast' in empty.stderr, empty cases = {