44 push :
55 tags :
66 - " v*"
7+ workflow_dispatch :
78
89jobs :
910 build :
@@ -15,12 +16,10 @@ jobs:
1516 include :
1617 - arch : x86_64
1718 runs-on : ubuntu-latest
18- target : x86_64
1919 triple : x86_64-bugleos-linux-musl
2020 label : x86_64
2121 - arch : aarch64
2222 runs-on : ubuntu-24.04-arm
23- target : aarch64
2423 triple : aarch64-bugleos-linux-musl
2524 label : aarch64
2625 permissions :
3130 with :
3231 fetch-depth : 0
3332
33+ - name : Read package versions
34+ shell : bash
35+ run : |
36+ set -euo pipefail
37+ binutils_version="$(awk -F ' := ' '/^BINUTILS_VERSION/ {print $2; exit}' make/binutils-stage1.mk)"
38+ gcc_version="$(awk -F ' := ' '/^GCC_VERSION/ {print $2; exit}' make/gcc-stage1.mk)"
39+ musl_version="$(awk -F ' := ' '/^MUSL_VERSION/ {print $2; exit}' make/musl.mk)"
40+ linux_version="$(awk -F ' := ' '/^LINUX_VERSION/ {print $2; exit}' make/linux-headers.mk)"
41+
42+ if [ -z "$binutils_version" ] || [ -z "$gcc_version" ] || [ -z "$musl_version" ] || [ -z "$linux_version" ]; then
43+ echo "Failed to read one or more package versions." >&2
44+ exit 1
45+ fi
46+
47+ echo "BINUTILS_VERSION=${binutils_version}" >> "$GITHUB_ENV"
48+ echo "GCC_VERSION=${gcc_version}" >> "$GITHUB_ENV"
49+ echo "MUSL_VERSION=${musl_version}" >> "$GITHUB_ENV"
50+ echo "LINUX_VERSION=${linux_version}" >> "$GITHUB_ENV"
51+ echo "VERSIONS_KEY=binutils-${binutils_version}-gcc-${gcc_version}-musl-${musl_version}-linux-${linux_version}" >> "$GITHUB_ENV"
52+
3453 - name : Validate tag format
3554 run : |
3655 set -euo pipefail
4968 build-essential binutils bash coreutils tar gzip xz-utils bison flex texinfo gawk file curl wget gpg \
5069 libgmp-dev libmpfr-dev libmpc-dev python3
5170
71+ - name : Restore download cache
72+ uses : actions/cache@v4
73+ with :
74+ path : |
75+ downloads/
76+ sources/
77+ key : downloads-${{ runner.os }}-${{ matrix.arch }}-${{ env.VERSIONS_KEY }}
78+
79+ - name : Restore build cache
80+ uses : actions/cache@v4
81+ with :
82+ path : |
83+ builds/
84+ out/progress/
85+ out/toolchain/
86+ out/toolchain-stage1/
87+ key : build-${{ runner.os }}-${{ matrix.arch }}-${{ env.VERSIONS_KEY }}-${{ hashFiles('Makefile', 'make/*.mk', 'config/*.mk', 'scripts/*.sh') }}
88+
5289 - name : Fetch sources
5390 run : |
5491 set -euo pipefail
@@ -59,10 +96,35 @@ jobs:
5996 set -euo pipefail
6097 ./scripts/verify-checksums.sh
6198
62- - name : Build ${{ matrix.arch }} toolchain
99+ - name : Build binutils stage1
100+ run : |
101+ set -euo pipefail
102+ make TARGET=${{ matrix.triple }} binutils-stage1
103+
104+ - name : Build Linux headers
105+ run : |
106+ set -euo pipefail
107+ make TARGET=${{ matrix.triple }} linux-headers
108+
109+ - name : Build GCC stage1
63110 run : |
64111 set -euo pipefail
65- make ${{ matrix.target }}
112+ make TARGET=${{ matrix.triple }} gcc-stage1
113+
114+ - name : Build musl
115+ run : |
116+ set -euo pipefail
117+ make TARGET=${{ matrix.triple }} musl
118+
119+ - name : Build binutils stage2
120+ run : |
121+ set -euo pipefail
122+ make TARGET=${{ matrix.triple }} binutils-stage2
123+
124+ - name : Build GCC stage2
125+ run : |
126+ set -euo pipefail
127+ make TARGET=${{ matrix.triple }} gcc-stage2
66128
67129 - name : Upload build logs
68130 if : always()
@@ -92,6 +154,39 @@ jobs:
92154 path : dist/bugleos-toolchain-${{ env.VERSION }}-${{ matrix.label }}.tar.gz
93155 if-no-files-found : error
94156
157+ hash-artifacts :
158+ name : Prepare SLSA subjects
159+ runs-on : ubuntu-latest
160+ needs : build
161+ outputs :
162+ base64_subjects : ${{ steps.hashes.outputs.base64_subjects }}
163+ steps :
164+ - name : Download toolchain tarballs
165+ uses : actions/download-artifact@v4
166+ with :
167+ path : dist
168+
169+ - name : Compute base64 subjects
170+ id : hashes
171+ shell : bash
172+ run : |
173+ set -euo pipefail
174+ mapfile -d '' files < <(find dist -name 'bugleos-toolchain-*.tar.gz' -print0 | sort -z)
175+ if [ "${#files[@]}" -eq 0 ]; then
176+ echo "No toolchain tarballs found under dist/." >&2
177+ exit 1
178+ fi
179+
180+ tmp="$(mktemp)"
181+ for f in "${files[@]}"; do
182+ hash="$(sha256sum "$f" | awk '{print $1}')"
183+ name="$(basename "$f")"
184+ printf '%s %s\n' "$hash" "$name" >> "$tmp"
185+ done
186+
187+ sort "$tmp" | base64 -w0 > "$tmp.b64"
188+ echo "base64_subjects=$(cat "$tmp.b64")" >> "$GITHUB_OUTPUT"
189+
95190 publish :
96191 name : Publish Release
97192 runs-on : ubuntu-latest
@@ -115,6 +210,71 @@ jobs:
115210 echo "PRERELEASE=false" >> "$GITHUB_ENV"
116211 fi
117212
213+ - name : Install signing tools
214+ run : |
215+ sudo apt-get update
216+ sudo apt-get install -y minisign gnupg
217+
218+ - name : Install SBOM tool (syft)
219+ run : |
220+ set -euo pipefail
221+ curl -sSfL https://get.anchore.io/syft | sh -s -- -b /usr/local/bin
222+ syft version
223+
224+ - name : Generate SBOMs (SPDX + CycloneDX)
225+ run : |
226+ set -euo pipefail
227+ mapfile -d '' files < <(find dist -name 'bugleos-toolchain-*.tar.gz' -print0 | sort -z)
228+ if [ "${#files[@]}" -eq 0 ]; then
229+ echo "No toolchain tarballs found under dist/." >&2
230+ exit 1
231+ fi
232+
233+ for f in "${files[@]}"; do
234+ base="$(basename "$f" .tar.gz)"
235+ workdir="$(mktemp -d)"
236+ tar -C "$workdir" -xzf "$f"
237+ syft "dir:$workdir" -o spdx-json > "dist/${base}.spdx.json"
238+ syft "dir:$workdir" -o cyclonedx-json > "dist/${base}.cdx.json"
239+ rm -rf "$workdir"
240+ done
241+
242+ - name : Generate SHA256SUMS and signatures
243+ env :
244+ MINISIGN_KEY : ${{ secrets.MINISIGN_KEY }}
245+ MINISIGN_PUB : ${{ secrets.MINISIGN_PUB }}
246+ run : |
247+ set -euo pipefail
248+
249+ if [ -z "${MINISIGN_KEY:-}" ] || [ -z "${MINISIGN_PUB:-}" ]; then
250+ echo "Missing minisign secrets (MINISIGN_KEY / MINISIGN_PUB)." >&2
251+ exit 1
252+ fi
253+
254+ mkdir -p out dist
255+ printf '%s' "$MINISIGN_KEY" | base64 -d > out/minisign.key
256+ printf '%s' "$MINISIGN_PUB" | base64 -d > out/minisign.pub
257+ chmod 600 out/minisign.key
258+ cp out/minisign.pub dist/minisign.pub
259+
260+ mapfile -d '' files < <(find dist -name 'bugleos-toolchain-*.tar.gz' -print0 | sort -z)
261+ if [ "${#files[@]}" -eq 0 ]; then
262+ echo "No toolchain tarballs found under dist/." >&2
263+ exit 1
264+ fi
265+
266+ mapfile -d '' sboms < <(find dist -maxdepth 1 \( -name 'bugleos-toolchain-*.spdx.json' -o -name 'bugleos-toolchain-*.cdx.json' \) -print0 | sort -z)
267+ if [ "${#sboms[@]}" -eq 0 ]; then
268+ echo "No SBOM files found under dist/." >&2
269+ exit 1
270+ fi
271+
272+ sha256sum "${files[@]}" "${sboms[@]}" > dist/SHA256SUMS
273+ minisign -S -s out/minisign.key -m dist/SHA256SUMS
274+ for f in "${files[@]}"; do
275+ minisign -S -s out/minisign.key -m "$f"
276+ done
277+
118278 - name : Publish GitHub Release
119279 uses : softprops/action-gh-release@v2
120280 with :
@@ -123,11 +283,44 @@ jobs:
123283 draft : false
124284 prerelease : ${{ env.PRERELEASE }}
125285 body : |
126- Supported architectures:
127- Architecture | Download Link
128- ------------ | -------------
129- x86_64 | [bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz](dist/**/bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz)
130- aarch64 | [bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz](dist/**/bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz)
286+ # Supported architectures
287+
288+ ## 
289+ - Toolchain: https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz
290+ - Signature (minisign): https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz.minisig
291+
292+ ## 
293+ - Toolchain: https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz
294+ - Signature (minisign): https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz.minisig
295+
296+ ## Verification
297+ - Public key: https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/minisign.pub
298+ - Checksums: https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/SHA256SUMS
299+ - Checksums signature: https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/SHA256SUMS.minisig
300+
131301 files : |
132302 dist/**/bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz
303+ dist/**/bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz.minisig
133304 dist/**/bugleos-toolchain-${{ env.VERSION }}-aarch64.tar.gz
305+ dist/**/bugleos-toolchain-${{ env.VERSION }}-x86_64.tar.gz.minisig
306+ dist/bugleos-toolchain-${{ env.VERSION }}-x86_64.spdx.json
307+ dist/bugleos-toolchain-${{ env.VERSION }}-aarch64.spdx.json
308+ dist/bugleos-toolchain-${{ env.VERSION }}-x86_64.cdx.json
309+ dist/bugleos-toolchain-${{ env.VERSION }}-aarch64.cdx.json
310+ dist/SHA256SUMS
311+ dist/SHA256SUMS.minisig
312+ dist/minisign.pub
313+
314+ provenance :
315+ name : Generate SLSA provenance
316+ needs : [hash-artifacts, publish]
317+ permissions :
318+ actions : read
319+ id-token : write
320+ contents : write
321+ uses : slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
322+ with :
323+ base64-subjects : " ${{ needs.hash-artifacts.outputs.base64_subjects }}"
324+ upload-assets : true
325+ upload-tag-name : ${{ github.ref_name }}
326+ provenance-name : bugleos-toolchain-${{ github.ref_name }}.intoto.jsonl
0 commit comments