11name : release
22
3- # TODO: musl.cc blocks GitHub Actions (since 2025-05). Re-enable the tag
4- # trigger once toolchains are mirrored or an alternative source is set up.
5- # on:
6- # push:
7- # tags:
8- # - 'v*'
3+ # Cross-compiled static release binaries, one per architecture.
4+ #
5+ # Toolchains come from cross-tools/musl-cross GitHub Releases
6+ # (https://github.com/cross-tools/musl-cross/releases): musl, fetched over
7+ # GitHub (musl.cc blocks GitHub Actions), and broad enough to cover every arch
8+ # kasld targets — including loongarch64, which musl.cc never provided.
99on :
10+ push :
11+ tags :
12+ - ' v*'
1013 workflow_dispatch :
14+ inputs :
15+ toolchain_version :
16+ description : ' cross-tools/musl-cross release tag to use (blank = latest)'
17+ required : false
18+ default : ' '
1119
1220permissions :
1321 contents : write
1422
1523jobs :
24+ # Resolve the toolchain release once so every arch builds against the same
25+ # version. Defaults to the latest release; pin via the workflow_dispatch input
26+ # to reproduce an older build.
27+ resolve-toolchain :
28+ runs-on : ubuntu-latest
29+ outputs :
30+ version : ${{ steps.resolve.outputs.version }}
31+ steps :
32+ - name : Resolve cross-tools/musl-cross version
33+ id : resolve
34+ env :
35+ GH_TOKEN : ${{ github.token }}
36+ INPUT_VERSION : ${{ inputs.toolchain_version }}
37+ run : |
38+ set -euo pipefail
39+ if [ -n "${INPUT_VERSION:-}" ]; then
40+ VER="${INPUT_VERSION}"
41+ else
42+ VER=$(gh api repos/cross-tools/musl-cross/releases/latest --jq .tag_name)
43+ fi
44+ echo "Using cross-tools/musl-cross ${VER}"
45+ echo "version=${VER}" >> "$GITHUB_OUTPUT"
46+
1647 build-release :
48+ needs : resolve-toolchain
1749 runs-on : ubuntu-latest
1850 strategy :
1951 fail-fast : false
2052 matrix :
53+ # arch: friendly name, used only in the artifact / tarball name.
54+ # musl_triple: cross-tools/musl-cross triple — the tar.xz stem, the
55+ # extracted directory name, and the <triple>-gcc prefix.
2156 include :
22- # --- Primary CTF targets ---
23- - arch : x86_64
24- musl_triple : x86_64-linux-musl
25- native_test : true
26- - arch : aarch64
27- musl_triple : aarch64-linux-musl
28- - arch : i686
29- musl_triple : i686-linux-musl
30- # --- ARM variants ---
31- - arch : arm
32- musl_triple : arm-linux-musleabi
33- - arch : armeb
34- musl_triple : armeb-linux-musleabi
35- - arch : armv7l
36- musl_triple : armv7l-linux-musleabihf
37- # --- MIPS ---
38- - arch : mips
39- musl_triple : mips-linux-musl
40- - arch : mipsel
41- musl_triple : mipsel-linux-musl
42- - arch : mips64
43- musl_triple : mips64-linux-musl
44- - arch : mips64el
45- musl_triple : mips64el-linux-musl
46- # --- POWER ---
47- - arch : powerpc64
48- musl_triple : powerpc64-linux-musl
49- - arch : powerpc64le
50- musl_triple : powerpc64le-linux-musl
51- # --- RISC-V ---
52- - arch : riscv64
53- musl_triple : riscv64-linux-musl
57+ # --- x86 ---
58+ - { arch: x86_64, musl_triple: x86_64-unknown-linux-musl, native_test: true }
59+ - { arch: i686, musl_triple: i686-unknown-linux-musl }
60+ - { arch: i586, musl_triple: i586-unknown-linux-musl } # older x86 baseline
61+ # --- ARM (soft/hard float, v6/v7) ---
62+ # NOTE: armeb (big-endian ARM) is intentionally omitted — cross-tools/
63+ # musl-cross ships no armeb toolchain. Re-add if a source appears.
64+ - { arch: aarch64, musl_triple: aarch64-unknown-linux-musl }
65+ - { arch: arm, musl_triple: arm-unknown-linux-musleabi } # v6 soft-float
66+ - { arch: armhf, musl_triple: arm-unknown-linux-musleabihf } # v6 hard-float
67+ - { arch: armv7, musl_triple: armv7-unknown-linux-musleabi } # v7 soft-float
68+ - { arch: armv7l, musl_triple: armv7-unknown-linux-musleabihf } # v7 hard-float
69+ # --- MIPS (hard/soft float, BE/LE) ---
70+ - { arch: mips, musl_triple: mips-unknown-linux-musl }
71+ - { arch: mipssf, musl_triple: mips-unknown-linux-muslsf } # soft-float
72+ - { arch: mipsel, musl_triple: mipsel-unknown-linux-musl }
73+ - { arch: mipselsf, musl_triple: mipsel-unknown-linux-muslsf } # soft-float
74+ - { arch: mips64, musl_triple: mips64-unknown-linux-musl }
75+ - { arch: mips64el, musl_triple: mips64el-unknown-linux-musl }
76+ # --- POWER (32/64, BE/LE) ---
77+ - { arch: powerpc, musl_triple: powerpc-unknown-linux-musl } # ppc32 BE
78+ - { arch: powerpcle, musl_triple: powerpcle-unknown-linux-musl } # ppc32 LE
79+ - { arch: powerpc64, musl_triple: powerpc64-unknown-linux-musl }
80+ - { arch: powerpc64le, musl_triple: powerpc64le-unknown-linux-musl }
81+ # --- RISC-V (32/64) ---
82+ - { arch: riscv32, musl_triple: riscv32-unknown-linux-musl }
83+ - { arch: riscv64, musl_triple: riscv64-unknown-linux-musl }
5484 # --- s390x ---
55- - arch : s390x
56- musl_triple : s390x-linux-musl
57- # TODO: loongarch64 — musl.cc does not provide a toolchain yet.
58- # Add when available or mirror a custom-built one.
85+ - { arch: s390x, musl_triple: s390x-ibm-linux-musl }
86+ # --- LoongArch ---
87+ - { arch: loongarch64, musl_triple: loongarch64-unknown-linux-musl }
88+
89+ env :
90+ TC_VERSION : ${{ needs.resolve-toolchain.outputs.version }}
5991
6092 steps :
6193 - uses : actions/checkout@v6
6294
63- - name : Download musl cross-compiler
95+ - name : Download + verify musl cross-compiler
6496 run : |
65- curl -fsSL "https://musl.cc/${{ matrix.musl_triple }}-cross.tgz" \
66- | tar xz -C /opt
67- echo "/opt/${{ matrix.musl_triple }}-cross/bin" >> "$GITHUB_PATH"
97+ set -euo pipefail
98+ base="https://github.com/cross-tools/musl-cross/releases/download/${TC_VERSION}"
99+ tarball="${{ matrix.musl_triple }}.tar.xz"
100+ # Retry: the releases CDN occasionally returns a transient 5xx.
101+ dl() { curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "$1" -o "$2"; }
102+ dl "${base}/${tarball}" "${tarball}"
103+ dl "${base}/${tarball}.sha256" "${tarball}.sha256"
104+ # The .sha256 file holds only the bare digest, so pair it with the
105+ # local filename before checking.
106+ echo "$(cut -d' ' -f1 "${tarball}.sha256") ${tarball}" | sha256sum -c -
107+ mkdir -p "${RUNNER_TEMP}/toolchain"
108+ tar -xJf "${tarball}" -C "${RUNNER_TEMP}/toolchain"
109+ echo "${RUNNER_TEMP}/toolchain/${{ matrix.musl_triple }}/bin" >> "$GITHUB_PATH"
68110
69111 - name : Build static binaries
70112 run : make build CC=${{ matrix.musl_triple }}-gcc
71113
72114 - name : Identify build directory
73115 id : builddir
74- run : |
75- ARCH=$(${{ matrix.musl_triple }}-gcc -dumpmachine)
76- echo "dir=build/${ARCH}" >> "$GITHUB_OUTPUT"
116+ run : echo "dir=build/$(${{ matrix.musl_triple }}-gcc -dumpmachine)" >> "$GITHUB_OUTPUT"
77117
78118 - name : Verify static linkage
79119 run : |
@@ -86,11 +126,14 @@ jobs:
86126
87127 - name : Package release tarball
88128 run : |
129+ set -euo pipefail
89130 TAG="${GITHUB_REF_NAME}"
90131 DIR="kasld-${TAG}-${{ matrix.arch }}"
91132 mkdir -p "${DIR}"
92- cp "${{ steps.builddir.outputs.dir }}/kasld" "${DIR}/"
93- cp -r "${{ steps.builddir.outputs.dir }}/components" "${DIR}/"
133+ # Ship the build/<arch> output (kasld + components/), minus the .o
134+ # build intermediates.
135+ cp -a "${{ steps.builddir.outputs.dir }}/." "${DIR}/"
136+ find "${DIR}" -name '*.o' -delete
94137 cp README.md LICENSE "${DIR}/"
95138 tar czf "${DIR}.tar.gz" "${DIR}"
96139 sha256sum "${DIR}.tar.gz" > "${DIR}.tar.gz.sha256"
@@ -105,6 +148,9 @@ jobs:
105148
106149 create-release :
107150 needs : build-release
151+ # Only publish a release for tag pushes; workflow_dispatch runs build the
152+ # artifacts (for testing) without creating one.
153+ if : startsWith(github.ref, 'refs/tags/')
108154 runs-on : ubuntu-latest
109155 steps :
110156 - uses : actions/download-artifact@v5
0 commit comments