Skip to content

Commit 2cf5a9a

Browse files
f355andypugh
authored andcommitted
[ci] publish releases with artifacts
* before this, CI built packages but didn’t create a release with downloadable .deb's, now it does, for both amd64 and arm64 architectures and three Debian versions: bookworm, trixie and sid. * in order to make the .deb versioning better, version detection has been changed - on tagged commits, packages use the tag verbatim; otherwise the prevous logic is preserved. * tag matching on master is derived from VERSION (major.minor) instead of hard‑coded. This yields versions that align with release tags and clearer pre‑release identifiers.
1 parent 308862e commit 2cf5a9a

File tree

3 files changed

+153
-15
lines changed

3 files changed

+153
-15
lines changed

.github/workflows/ci.yml

Lines changed: 135 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ jobs:
8686
# Note that the package build covers html docs
8787
8888
package-arch:
89-
runs-on: ubuntu-latest
89+
runs-on: ${{ matrix.runner }}
9090
strategy:
9191
matrix:
92-
image: ["debian:bullseye", "debian:bookworm", "debian:sid"]
93-
92+
runner: ["ubuntu-24.04", "ubuntu-24.04-arm"]
93+
image: ["debian:bullseye", "debian:bookworm", "debian:trixie", "debian:sid"]
9494
container:
9595
image: ${{ matrix.image }}
9696
# IPC_OWNER is needed for shmget IPC_CREAT
@@ -123,7 +123,7 @@ jobs:
123123
DEBIAN_FRONTEND: noninteractive
124124
run: |
125125
case "${{matrix.image}}" in
126-
debian:sid|debian:bookworm)
126+
debian:sid|debian:bookworm|debian:trixie)
127127
exit 0
128128
;;
129129
*)
@@ -165,12 +165,37 @@ jobs:
165165
eatmydata adduser testrunner sudo
166166
chmod 0777 $(find tests/ -type d) # make test dirs world-writable for the testrunner
167167
su -c "eatmydata ./scripts/runtests -p ./tests" testrunner
168+
- name: Gather build artifacts
169+
run: |
170+
set -e
171+
set -x
172+
ARCH=$(dpkg --print-architecture)
173+
DIST=$(echo ${{ matrix.image }} | cut -d : -f 2)
174+
OUTDIR="artifacts/${DIST}/${ARCH}"
175+
mkdir -p "$OUTDIR"
176+
cp -v ../*.deb ../*.changes ../*.buildinfo "$OUTDIR" || true
177+
(cd "$OUTDIR" && sha256sum * > SHA256SUMS.txt)
178+
echo "DIST=$DIST" >> "$GITHUB_ENV"
179+
echo "ARCH=$ARCH" >> "$GITHUB_ENV"
180+
- name: Compute artifact metadata
181+
id: meta
182+
run: |
183+
echo "dist=$(echo ${{ matrix.image }} | cut -d : -f 2)" >> $GITHUB_OUTPUT
184+
echo "arch=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT
185+
186+
- name: Upload build artifacts
187+
uses: actions/upload-artifact@v4
188+
with:
189+
name: linuxcnc-${{ steps.meta.outputs.dist }}-${{ steps.meta.outputs.arch }}
190+
path: artifacts/${{ steps.meta.outputs.dist }}/${{ steps.meta.outputs.arch }}
191+
if-no-files-found: error
192+
168193

169194
package-indep:
170195
runs-on: ubuntu-latest
171196
strategy:
172197
matrix:
173-
image: ["debian:bullseye", "debian:bookworm", "debian:sid"]
198+
image: ["debian:bullseye", "debian:bookworm", "debian:trixie", "debian:sid"]
174199
container:
175200
image: ${{ matrix.image }}
176201
# IPC_OWNER is needed for shmget IPC_CREAT
@@ -204,7 +229,7 @@ jobs:
204229
DEBIAN_FRONTEND: noninteractive
205230
run: |
206231
case "${{matrix.image}}" in
207-
debian:sid|debian:bookworm)
232+
debian:sid|debian:bookworm|debian:trixie)
208233
exit 0
209234
;;
210235
*)
@@ -240,3 +265,107 @@ jobs:
240265
set -e
241266
set -x
242267
eatmydata apt-get --yes --quiet install ../*.deb
268+
- name: Gather build artifacts
269+
run: |
270+
set -e
271+
set -x
272+
DIST=$(echo ${{ matrix.image }} | cut -d : -f 2)
273+
ARCH=all
274+
OUTDIR="artifacts/${DIST}/${ARCH}"
275+
mkdir -p "$OUTDIR"
276+
cp -v ../*.deb ../*.changes ../*.buildinfo "$OUTDIR" || true
277+
(cd "$OUTDIR" && sha256sum * > SHA256SUMS.txt)
278+
echo "DIST=$DIST" >> "$GITHUB_ENV"
279+
echo "ARCH=$ARCH" >> "$GITHUB_ENV"
280+
- name: Compute artifact metadata
281+
id: meta
282+
run: |
283+
echo "dist=$(echo ${{ matrix.image }} | cut -d : -f 2)" >> $GITHUB_OUTPUT
284+
echo "arch=all" >> $GITHUB_OUTPUT
285+
286+
- name: Upload build artifacts
287+
uses: actions/upload-artifact@v4
288+
with:
289+
name: linuxcnc-${{ steps.meta.outputs.dist }}-${{ steps.meta.outputs.arch }}
290+
path: artifacts/${{ steps.meta.outputs.dist }}/${{ steps.meta.outputs.arch }}
291+
if-no-files-found: error
292+
293+
294+
cppcheck:
295+
runs-on: ubuntu-24.04
296+
steps:
297+
- uses: actions/checkout@v2
298+
with:
299+
submodules: true
300+
fetch-depth: 0
301+
- name: Perform Source Code checks that were successful in the past
302+
continue-on-error: true
303+
run: |
304+
set -x
305+
git fetch --recurse-submodules=no https://github.com/linuxcnc/linuxcnc refs/tags/*:refs/tags/*
306+
sudo apt-get -y install cppcheck shellcheck
307+
scripts/cppcheck.sh
308+
- name: Shellcheck
309+
continue-on-error: true
310+
run: |
311+
scripts/shellcheck.sh
312+
313+
314+
release:
315+
name: Release packages
316+
needs:
317+
- package-arch
318+
- package-indep
319+
if: (github.event_name == 'release' && github.event.action == 'published') || startsWith(github.ref, 'refs/tags/')
320+
permissions:
321+
contents: write
322+
runs-on: ubuntu-24.04
323+
steps:
324+
- name: Download artifacts
325+
uses: actions/download-artifact@v4
326+
with:
327+
path: release_artifacts
328+
- name: Prepare upload assets
329+
run: |
330+
set -e
331+
mkdir -p upload
332+
echo "Downloaded artifacts layout:" && find release_artifacts -maxdepth 3 -print | sed 's/^/ /'
333+
for d in release_artifacts/*; do
334+
[ -d "$d" ] || continue
335+
name=$(basename "$d")
336+
# Expect name like linuxcnc-bookworm-amd64 or linuxcnc-trixie-all
337+
dist=${name#linuxcnc-}
338+
dist=${dist%-*}
339+
arch=${name##*-}
340+
echo "Processing artifact: $name (dist=$dist arch=$arch)"
341+
# Copy .deb files with distro suffix (arch is already in Debian filename)
342+
for f in "$d"/*.deb; do
343+
[ -f "$f" ] || continue
344+
base=$(basename "$f")
345+
base_no_ext="${base%.deb}"
346+
dest="upload/${base_no_ext}_${dist}.deb"
347+
echo " + $base -> $(basename "$dest")"
348+
cp "$f" "$dest"
349+
done
350+
done
351+
352+
echo "Upload dir contents:" && ls -l upload | sed 's/^/ /'
353+
# Single combined checksums file for all assets, deterministic order
354+
if ls upload/*.deb >/dev/null 2>&1; then
355+
(
356+
cd upload
357+
: > SHA256SUMS.txt
358+
# sort file list for stable output
359+
for f in $(ls -1 *.deb | LC_ALL=C sort); do
360+
sha256sum "$f" >> SHA256SUMS.txt
361+
done
362+
echo "Preview of SHA256SUMS.txt:" && sed -n '1,200p' SHA256SUMS.txt | sed 's/^/ /'
363+
)
364+
fi
365+
- name: Create GitHub Release and upload assets
366+
uses: softprops/action-gh-release@v2
367+
with:
368+
files: |
369+
upload/*
370+
env:
371+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

scripts/get-version-from-git

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@ fi
99
githelper $1
1010

1111
if [ "$DEB_COMPONENT" = "scratch" ]; then
12-
# unknown branches get the VERSION file, plus the branch name (with any
13-
# characters that are invalid in debian version numbers replaced with
14-
# dashes '-'), plus the HEAD commit SHA1
15-
echo v$(git show HEAD:VERSION | cut -d ' ' -f 1)~${GIT_BRANCH//[^-.+:~a-z0-9]/-}~$(git show --pretty=format:%h HEAD | head -1)
12+
13+
DESCRIBE=$(git describe --tags --exact-match 2>/dev/null)
14+
if [ -n "$DESCRIBE" ]; then
15+
echo "$DESCRIBE"
16+
else
17+
DESCRIBE=$(git describe --tags 2>/dev/null)
18+
if [ -n "$DESCRIBE" ]; then
19+
echo "$DESCRIBE"
20+
else
21+
BR=$(printf '%s' "$GIT_BRANCH" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^-.+:~a-z0-9]/-/g; s/-{2,}/-/g; s/^-//; s/-$//')
22+
echo "v$(git show HEAD:VERSION | cut -d ' ' -f 1)~${BR:-head}~$(git show --pretty=format:%h HEAD | head -1)"
23+
fi
24+
fi
1625
else
1726
# known branches get the "describe" of the most recent signed git tag,
1827
# or of the most recent unsigned tag if no signed tags are found

scripts/githelper.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616

1717
function githelper() {
1818
if [ -z "$1" ]; then
19-
GIT_BRANCH=$(git branch | egrep '^\*' | cut -d ' ' -f 2)
20-
if [ "$GIT_BRANCH" = "(no" ]; then
21-
echo "'git branch' says we're not on a branch, pass one in as an argument" > /dev/null 1>&2
22-
return
19+
GIT_BRANCH=$(git symbolic-ref -q --short HEAD 2>/dev/null)
20+
if [ -z "$GIT_BRANCH" ]; then
21+
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
2322
fi
2423
else
2524
GIT_BRANCH="$1"
2625
fi
2726

2827
case $GIT_BRANCH in
2928
master)
30-
GIT_TAG_GLOB="v2.10.*"
29+
MM=$(git show HEAD:VERSION | sed -E 's/^([0-9]+)\.([0-9]+).*/\1.\2/')
30+
GIT_TAG_GLOB="v${MM}.*"
3131
DEB_COMPONENT="master"
3232
;;
3333
# release branches have names matching "number.number", which is awkward to express as a glob

0 commit comments

Comments
 (0)