Crafter.Build/.forgejo/workflows/ci.yaml

157 lines
7.2 KiB
YAML
Raw Normal View History

V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
name: CI
on:
pull_request:
branches: [master]
push:
branches: [master]
workflow_dispatch:
jobs:
build-test-release:
runs-on: arch-latest
env:
# x86-64-v2 = SSE4.2 baseline; runs on the CI SBC (Intel N5105 / Tremont,
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
# no AVX) and on essentially every x86_64 CPU since ~2011. The bootstrap
# MUST stay v2 — anything higher would emit instructions the SBC can't
# execute and the bootstrap binary itself would crash before it could
# rebuild for higher levels. v3/v4 variants are produced from this v2
# bootstrap by re-running it with CRAFTER_BUILD_MARCH overridden.
CRAFTER_BUILD_MARCH: x86-64-v2
CRAFTER_BUILD_MTUNE: generic
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
steps:
- name: Install build dependencies
run: |
# The slim archlinux:latest image arrives without a populated
# pacman keyring AND without a local pacman master key, so:
# 1. --init generates the local signing key (needed when pacman
# itself rewrites the keyring during package upgrades)
# 2. --populate archlinux imports the upstream master keys so
# currently-shipping signatures verify
# After that we can refresh archlinux-keyring to pick up keys for
# packagers added after the image's snapshot, then -Syu the rest.
pacman-key --init
pacman-key --populate archlinux
pacman -Sy --noconfirm --needed archlinux-keyring
pacman -Syu --noconfirm --needed \
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
base-devel git zip tar \
clang lld libc++ cmake \
mingw-w64-gcc \
wasi-libc wasi-libc++ wasi-libc++abi wasi-compiler-rt \
nodejs
# The container runs as root and the workspace may be owned by a
# different uid; tell git not to refuse operations on it.
git config --global --add safe.directory '*'
- name: Checkout
uses: actions/checkout@v4
with:
# Persist the auth token so the 'Update rolling latest tag' step
# below can push the tag back via the implicit GITHUB_TOKEN.
persist-credentials: true
- name: Cache glslang clone+build
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
# Cache covers crafter-build's per-(target, march) external dep cache.
# First run builds glslang up to 6 times (3 marches × 2 targets); the
# cache makes subsequent runs reuse those builds.
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
uses: actions/cache@v4
with:
path: |
~/.cache/crafter.build/external
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
key: glslang-${{ runner.os }}-v2
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
- name: Bootstrap (build.sh)
run: ./build.sh
- name: Run tests
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build test
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
- name: Build Linux x86-64-v2 (matches bootstrap)
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build
- name: Build Linux x86-64-v3
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build CRAFTER_BUILD_MARCH=x86-64-v3 ./bin/crafter-build
- name: Build Linux x86-64-v4
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build CRAFTER_BUILD_MARCH=x86-64-v4 ./bin/crafter-build
- name: Build Windows x86-64-v2 (mingw)
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build --target=x86_64-w64-mingw32
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
- name: Build Windows x86-64-v3 (mingw)
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build CRAFTER_BUILD_MARCH=x86-64-v3 ./bin/crafter-build --target=x86_64-w64-mingw32
- name: Build Windows x86-64-v4 (mingw)
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build CRAFTER_BUILD_MARCH=x86-64-v4 ./bin/crafter-build --target=x86_64-w64-mingw32
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
- name: Package artifacts
run: |
set -eux
mkdir -p dist
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
# 6 archives — 3 marches × 2 OSes. Each is self-contained: the
# Linux launcher is statically linked; the Windows launcher has
# crafter-build.dll + libcrafter-build.dll.a alongside the exe.
for march in x86-64-v2 x86-64-v3 x86-64-v4; do
stage_lin=$(mktemp -d)
mkdir -p "$stage_lin/bin" "$stage_lin/lib"
cp "bin/crafter.build-exe-x86_64-pc-linux-gnu-$march/crafter-build" "$stage_lin/bin/"
cp "bin/crafter.build-lib-x86_64-pc-linux-gnu-$march/libcrafter-build.a" "$stage_lin/lib/"
cp -r share "$stage_lin/"
tar czf "dist/crafter-build-linux-x86_64-$march.tar.gz" -C "$stage_lin" .
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
stage_win=$(mktemp -d)
mkdir -p "$stage_win/bin"
cp "bin/crafter.build-exe-x86_64-w64-mingw32-$march"/* "$stage_win/bin/"
cp -r share "$stage_win/"
(cd "$stage_win" && zip -r "$GITHUB_WORKSPACE/dist/crafter-build-windows-x86_64-$march.zip" .)
done
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
ls -la dist/
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
# Upload each archive as its own workflow artifact (one upload per file)
# so users browsing the PR / run page get six small, individually-named
# downloads instead of one wrapper zip containing the lot.
- name: Upload Linux v2 artifact
uses: actions/upload-artifact@v3
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
with: { name: crafter-build-linux-x86_64-v2, path: dist/crafter-build-linux-x86_64-v2.tar.gz, if-no-files-found: error }
- name: Upload Linux v3 artifact
uses: actions/upload-artifact@v3
with: { name: crafter-build-linux-x86_64-v3, path: dist/crafter-build-linux-x86_64-v3.tar.gz, if-no-files-found: error }
- name: Upload Linux v4 artifact
uses: actions/upload-artifact@v3
with: { name: crafter-build-linux-x86_64-v4, path: dist/crafter-build-linux-x86_64-v4.tar.gz, if-no-files-found: error }
- name: Upload Windows v2 artifact
uses: actions/upload-artifact@v3
with: { name: crafter-build-windows-x86_64-v2, path: dist/crafter-build-windows-x86_64-v2.zip, if-no-files-found: error }
- name: Upload Windows v3 artifact
uses: actions/upload-artifact@v3
with: { name: crafter-build-windows-x86_64-v3, path: dist/crafter-build-windows-x86_64-v3.zip, if-no-files-found: error }
- name: Upload Windows v4 artifact
uses: actions/upload-artifact@v3
with: { name: crafter-build-windows-x86_64-v4, path: dist/crafter-build-windows-x86_64-v4.zip, if-no-files-found: error }
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
- name: Update rolling 'latest' tag
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
run: |
git config user.email "ci@catcrafts.net"
git config user.name "Crafter Build CI"
git tag -f latest
git push origin latest --force
- name: Publish rolling 'latest' release
ci: ship per-march variants (v2/v3/v4) as individual artifacts Replaces the single Linux + single Windows tarball with six self- contained variants — three µarch levels × two OSes. End users on the Releases page see them as six individually-downloadable archives: crafter-build-{linux,windows}-x86_64-{v2,v3,v4}.{tar.gz,zip} Pick the v-level your CPU supports: v2: SSE4.2 baseline (every x86_64 since ~2011) v3: AVX2 + FMA + BMI (Intel Haswell+, AMD Excavator+, ~2013+) v4: AVX-512 (Skylake-X+, recent server-class) How: the bootstrap binary stays at v2 because the CI SBC (N5105 / Tremont, no AVX) can't execute v3 or v4 instructions and would crash before it could rebuild itself for higher levels. Once bootstrap's done, the same v2 binary is re-invoked with CRAFTER_BUILD_MARCH overridden per variant to produce v2/v3/v4 outputs. Same again with --target=x86_64-w64-mingw32 for the Windows variants. ExternalDependency cache keys on (url, target, march) already so glslang gets built per variant; subsequent CI runs hit the cache. Also drops the wrapper zip from workflow artifacts: instead of one upload-artifact call producing crafter-build.zip containing six archives, there's now one call per archive. The PR / run page shows six small downloads named for what they are. forgejo-release continues to upload release-dir/* as individual assets, so the Releases page already has the right shape — this just brings the workflow artifact UX in line. Bumped the glslang cache key to v2 (one-time invalidation) since the cache layout now needs space for six glslang builds rather than two. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 02:29:50 +02:00
# forgejo-release uploads each file in release-dir as a separate
# release asset, so the Releases page shows six individually
# downloadable archives — pick the v-level matching your CPU.
V2: WASI, -r flag, CI pipeline, examples & tests cleanup WASI / wasm32 target support - Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32") - Skip -march/-mtune for wasm (clang rejects them) - Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync) - .wasm output extension in expectedOutputFor and link command - EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html + runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL set in the templated index.html so a single shim handles any output name -r run flag in the CLI: build then exec the artifact (host targets only; rejects libraries; auto .exe/.wasm extension handling) CI pipeline (.forgejo/workflows/ci.yaml) - Triggers: PR/push to master + manual dispatch - Single arch-latest container job: install deps, bootstrap, self-rebuild, run tests, cross-compile mingw, package both archives, upload artifacts - Rolling 'latest' release published only on push/dispatch to master mingw cross-compile from Linux now works end-to-end: - ExternalDependency cache key includes target so per-target glslang builds don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends 'd' to lib names and breaks linking); cross-compile cmake flags (CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...) - project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh link pulls pthread which mingw doesn't link by default) - mingw compile uses -femulated-tls so std::__once_callable etc reference the same emutls symbols libstdc++ provides - mingw link auto-adds -lstdc++exp -lpthread GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux + Windows) now both use it instead of duplicating the resolution. Examples reorg: hello-world, library, with-module, wasi, tests — each with its own README. Tests reorg: per-test directory with inner/ fixture, no shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
uses: https://code.forgejo.org/actions/forgejo-release@v2
with:
direction: upload
url: ${{ github.server_url }}
repo: ${{ github.repository }}
tag: latest
title: Latest main build
prerelease: true
override: true
release-dir: dist
token: ${{ secrets.GITHUB_TOKEN }}