A push to master published the `beta` branch and moved the rolling `latest` tag and its "Latest master build" prerelease, and a pushed X.Y.Z tag made the release and published `stable`. The owner wants a release for every push to master, made by the signed tag that goes with it, and nothing for a push without one. So `beta`, `latest` and the branch trigger are gone: the workflow runs for pushed tags, pull requests and manual runs only, and the `latest` tag and its prerelease have been deleted from the forge. `beta` gets no more builds, and its installations would not hear of it: the release notes ship in stable builds only. The Publish step marks beta's last build end-of-life, once, with a reason that names stable, and the next `flatpak update` of a beta installation prints it. The reason also names the branch, because a non-interactive update prints only the app's name with it. Before building, a tag run now checks the tag: it has to be annotated and signed by the owner as Forgejo verifies it, its commit has to be on master, its version has to be X.Y.Z and newer than every release the forge has published, its own included (a later tag whose run still queues does not count), and the metainfo's newest <release> entry has to be that version. The tag run checked only the last of these. It reads the tag from the forge's API, because the checkout fetches a pushed tag again as a plain ref to its commit, so the job's clone never has the annotated tag, and Forgejo verifies a signed tag's own signature but falls back to the commit's for an unsigned one, so the step also requires that the verdict covers the tag's payload. The metainfo's entry is read once, as the first <release> element: the Version step takes its version and renders its notes into release-notes.md with the renderer the Release notes step had, and stops the run when they come out empty, so a comment or another attribute order cannot give a release one entry's version and another's notes. It does so on every run, pull requests and manual runs included, so a broken entry shows before a release. Release runs share a concurrency group, so they queue one behind another; a pull request still cancels its own outdated run. A failed release run can be re-run while no newer release exists, since its tag is still on its commit; a release that an attempt left half made has to be deleted first. The release step runs without `override`, which would delete a tag that has moved off the run's commit since the Version step and tag the old commit instead. A manual run no longer publishes anything; it used to publish `beta` and move `latest` from whichever branch it was started on. No step pushes to git, so the checkout keeps no credentials. git describe in build.sh, project.cpp and the workflow has no `latest` tag left to exclude.
126 lines
5.5 KiB
Shell
Executable file
126 lines
5.5 KiB
Shell
Executable file
#!/bin/sh
|
|
#SPDX-License-Identifier: LGPL-3.0-only
|
|
#SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
# Bootstrap: compile crafter-build by hand, without crafter-build. The
|
|
# self-host build through project.cpp follows (`./bin/crafter-build`).
|
|
set -eu
|
|
|
|
# The toolchain. CRAFTER_BUILD_LLVM_DIR names an LLVM prefix (the Flatpak
|
|
# sets /app); otherwise the tools come from PATH. The same rule the built
|
|
# binary applies at run time (Crafter.Build:Toolchain).
|
|
if [ -n "${CRAFTER_BUILD_LLVM_DIR:-}" ]; then
|
|
CXX="$CRAFTER_BUILD_LLVM_DIR/bin/clang++"
|
|
CC="$CRAFTER_BUILD_LLVM_DIR/bin/clang"
|
|
AR="$CRAFTER_BUILD_LLVM_DIR/bin/llvm-ar"
|
|
LLVM_CONFIG="$CRAFTER_BUILD_LLVM_DIR/bin/llvm-config"
|
|
# A prefix other than the system one keeps its libc++ off both the
|
|
# linker's search path (clang looks in lib/<triple> and the system dirs,
|
|
# not <prefix>/lib) and the loader's; -L and an rpath cover the two.
|
|
if [ "$CRAFTER_BUILD_LLVM_DIR" != /usr ]; then
|
|
LIBCXX_LINK_FLAGS="-L$CRAFTER_BUILD_LLVM_DIR/lib -Wl,-rpath,$CRAFTER_BUILD_LLVM_DIR/lib"
|
|
else
|
|
LIBCXX_LINK_FLAGS=""
|
|
fi
|
|
if [ -f "$CRAFTER_BUILD_LLVM_DIR/share/libc++/v1/std.cppm" ]; then
|
|
STD_CPPM="$CRAFTER_BUILD_LLVM_DIR/share/libc++/v1/std.cppm"
|
|
else
|
|
STD_CPPM=/usr/share/libc++/v1/std.cppm
|
|
fi
|
|
else
|
|
CXX=clang++
|
|
CC=clang
|
|
AR=llvm-ar
|
|
LLVM_CONFIG=llvm-config
|
|
LIBCXX_LINK_FLAGS=""
|
|
STD_CPPM=/usr/share/libc++/v1/std.cppm
|
|
fi
|
|
|
|
# The version baked into the binary: the environment (CI sets it), else the
|
|
# nearest tag, else a development marker.
|
|
VERSION="${CRAFTER_BUILD_VERSION:-$(git describe --tags --always --dirty 2>/dev/null || echo 0.0.0-dev)}"
|
|
|
|
mkdir -p build bin lib share/crafter-build share/crafter-build/wasi-runtime
|
|
|
|
cp wasi-runtime/runtime.js share/crafter-build/wasi-runtime/
|
|
cp wasi-runtime/index.html.in share/crafter-build/wasi-runtime/
|
|
|
|
# Partition order is the import order: every unit is listed before the
|
|
# units that import it, and the umbrella last.
|
|
PARTITIONS="Toolchain Shader Platform Interface Implementation External Agents Clang Test Lint Script Progress Asset"
|
|
|
|
cp interfaces/Crafter.Build.cppm share/crafter-build/
|
|
for p in $PARTITIONS; do
|
|
cp "interfaces/Crafter.Build-$p.cppm" share/crafter-build/
|
|
done
|
|
|
|
if [ ! -d build/glslang/.git ]; then
|
|
git clone --depth 1 https://github.com/KhronosGroup/glslang.git build/glslang
|
|
fi
|
|
|
|
current_dir=$(pwd)
|
|
|
|
cd build/glslang
|
|
cmake -B build \
|
|
-DCMAKE_C_COMPILER="$CC" \
|
|
-DCMAKE_CXX_COMPILER="$CXX" \
|
|
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
|
|
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ $LIBCXX_LINK_FLAGS" \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++ $LIBCXX_LINK_FLAGS" \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$current_dir/build" \
|
|
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$current_dir/build" \
|
|
-DENABLE_OPT=OFF
|
|
cmake --build build --config Release
|
|
cd ../../
|
|
|
|
MARCH="${CRAFTER_BUILD_MARCH:-native}"
|
|
MTUNE="${CRAFTER_BUILD_MTUNE:-native}"
|
|
# The bootstrap targets the toolchain's own triple: x86_64-pc-linux-gnu on
|
|
# glibc distros, x86_64-unknown-linux-gnu for the bundled LLVM,
|
|
# x86_64-alpine-linux-musl on Alpine. Override with CRAFTER_BUILD_TARGET.
|
|
TARGET="${CRAFTER_BUILD_TARGET:-$("$CXX" -print-target-triple)}"
|
|
TARGET_DEFINE="CRAFTER_BUILD_CONFIGURATION_TARGET_$(printf '%s' "$TARGET" | tr - _)"
|
|
|
|
# Crafter.Build-Lint includes libclang's clang-c/Index.h. glibc distros keep
|
|
# it in /usr/include; other prefixes keep it under their own include dir, so
|
|
# ask llvm-config and add the dir when it is not already on the default path
|
|
# (never add /usr/include itself: that breaks libc++'s #include_next).
|
|
LLVM_INCDIR="$("$LLVM_CONFIG" --includedir 2>/dev/null || true)"
|
|
case "$LLVM_INCDIR" in ""|/usr/include) LLVM_INCFLAG="" ;; *) LLVM_INCFLAG="-I$LLVM_INCDIR" ;; esac
|
|
|
|
common_options="--target=$TARGET -stdlib=libc++ -I./build/glslang $LLVM_INCFLAG -std=c++26 -O3 -march=$MARCH -mtune=$MTUNE -fprebuilt-module-path=./build -D $TARGET_DEFINE -D CRAFTER_BUILD_CONFIGURATION_TYPE_EXECUTABLE -D CRAFTER_BUILD_VERSION=\"$VERSION\" -c"
|
|
|
|
"$CXX" --target="$TARGET" -std=c++26 -stdlib=libc++ -O3 -march="$MARCH" -mtune="$MTUNE" -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile "$STD_CPPM" -o ./build/std.pcm
|
|
|
|
# Asset partition: bootstrap compiles it WITHOUT CRAFTER_BUILD_HAS_ASSET so
|
|
# CompressAsset takes the stub branch and the impl unit doesn't try to
|
|
# `import Crafter.Asset` (no Crafter.Asset PCM exists at this stage — the
|
|
# self-host pass that follows wires in the real dep).
|
|
OBJECTS=""
|
|
for p in $PARTITIONS; do
|
|
"$CXX" $common_options -fmodule-output "interfaces/Crafter.Build-$p.cppm" -o "./build/Crafter.Build-$p.o"
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build-$p.o"
|
|
done
|
|
"$CXX" $common_options -fmodule-output interfaces/Crafter.Build.cppm -o ./build/Crafter.Build.o
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build.o"
|
|
|
|
for p in $PARTITIONS; do
|
|
"$CXX" $common_options "./implementations/Crafter.Build-$p.cpp" -o "./build/Crafter.Build-${p}_impl.o"
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build-${p}_impl.o"
|
|
done
|
|
"$CXX" $common_options ./implementations/main.cpp -o ./build/main.o
|
|
|
|
# A fresh archive each time: `ar rcs` into an existing one keeps members a
|
|
# previous layout left behind.
|
|
rm -f ./lib/libcrafter-build.a
|
|
"$AR" rcs ./lib/libcrafter-build.a $OBJECTS
|
|
|
|
"$CXX" --target="$TARGET" -std=c++26 -stdlib=libc++ -O3 -march="$MARCH" -mtune="$MTUNE" -fuse-ld=lld \
|
|
-Wl,--export-dynamic $LIBCXX_LINK_FLAGS \
|
|
-L./build \
|
|
$OBJECTS \
|
|
./build/main.o \
|
|
-lSPIRV -lGenericCodeGen -lglslang -lOSDependent -lMachineIndependent -lglslang-default-resource-limits \
|
|
-ldl \
|
|
-o ./bin/crafter-build
|