1212 matrix :
1313 goos : [linux, windows, darwin]
1414 goarch : [amd64, arm64]
15-
1615 steps :
1716 - name : Checkout code
1817 uses : actions/checkout@v4
@@ -24,12 +23,20 @@ jobs:
2423
2524 - name : Build binaries
2625 run : |
27- make build BINARY_NAME=coldwire-server GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }}
26+ make CI=true build \
27+ BINARY_NAME=coldwire-server \
28+ GOOS=${{ matrix.goos }} \
29+ GOARCH=${{ matrix.goarch }} \
30+ BIN_DIR=bin
31+ # make will create bin/<binary>-<os>-<arch>(.exe)
32+
33+ - name : Show bin contents (build)
34+ run : ls -la bin || true
2835
2936 - name : Upload artifacts
3037 uses : actions/upload-artifact@v4
3138 with :
32- # Use unique artifact name per OS/ARCH to avoid conflicts
39+ # Unique artifact name per OS/ARCH
3340 name : binaries-${{ matrix.goos }}-${{ matrix.goarch }}
3441 path : bin/*
3542
@@ -40,34 +47,95 @@ jobs:
4047 - name : Checkout code
4148 uses : actions/checkout@v4
4249
43- - name : Show downloaded files
44- run : ls -la bin || true
45-
4650 - name : Download build artifacts
4751 uses : actions/download-artifact@v4
4852 with :
4953 path : bin/
5054
55+ - name : Show downloaded tree
56+ run : |
57+ echo "=== bin before flattening ==="
58+ ls -laR bin || true
59+
60+ - name : Flatten artifacts into bin/
61+ run : |
62+ set -eu
63+ shopt -s nullglob || true
64+ # move files from per-artifact subfolders into bin/
65+ for d in bin/*; do
66+ if [ -d "$d" ]; then
67+ # move files (if any) up one level
68+ for f in "$d"/*; do
69+ # if there are files, move them
70+ if [ -e "$f" ]; then
71+ mv "$f" bin/ || true
72+ fi
73+ done
74+ # remove the (now likely empty) folder
75+ rmdir "$d" 2>/dev/null || true
76+ fi
77+ done
78+ echo "=== bin after flattening ==="
79+ ls -la bin || true
80+
5181 - name : Compute SHA256 checksums
5282 run : |
83+ set -eu
84+ mkdir -p bin
5385 echo "## Checksums" > bin/CHECKSUMS.md
54- for f in bin/*; do
55- sha256sum "$f" >> bin/CHECKSUMS.md
56- done
86+ # only files, skip the CHECKSUMS.md itself
87+ find bin -type f -not -name 'CHECKSUMS.md' -print0 | xargs -0 -n1 sha256sum >> bin/CHECKSUMS.md
5788 cat bin/CHECKSUMS.md
5889
5990 - name : Extract latest changelog section
6091 id : changelog
6192 run : |
93+ # Grab the latest "## [v..." section (lines after first match until the next '## [v' or EOF)
6294 latest_notes=$(awk '/^## \[v/{if (found) exit; found=1; next} found {print}' CHANGELOG.md)
95+ if [ -z "$latest_notes" ]; then
96+ latest_notes="(no changelog entry found)"
97+ fi
6398 echo "LATEST_NOTES<<EOF" >> $GITHUB_ENV
6499 echo "$latest_notes" >> $GITHUB_ENV
65100 echo "EOF" >> $GITHUB_ENV
66101
67- - name : Publish GitHub Release
68- run : |
69- gh release create "$GITHUB_REF_NAME" bin/* \
70- --title "Release $GITHUB_REF_NAME" \
71- --notes "$LATEST_NOTES"
102+ - name : Create GitHub Release
103+ id : create_release
104+ uses : actions/create-release@v1
105+ env :
106+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
107+ with :
108+ tag_name : ${{ github.ref_name }}
109+ release_name : Release ${{ github.ref_name }}
110+ body : ${{ env.LATEST_NOTES }}
111+ draft : false
112+ prerelease : false
113+
114+ - name : Upload release assets
72115 env :
73116 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
117+ UPLOAD_URL : ${{ steps.create_release.outputs.upload_url }}
118+ run : |
119+ set -eu
120+ # upload_url is a template like: https://uploads.github.com/repos/OWNER/REPO/releases/ID/assets{?name,label}
121+ # we need to strip the template braces part
122+ base_url="${UPLOAD_URL%\{*}"
123+ echo "Upload base URL: $base_url"
124+
125+ for f in bin/*; do
126+ if [ -f "$f" ]; then
127+ name=$(basename "$f")
128+ echo "Uploading $name ..."
129+ curl --fail -sS -X POST \
130+ -H "Authorization: Bearer $GITHUB_TOKEN" \
131+ -H "Content-Type: application/octet-stream" \
132+ --data-binary @"$f" \
133+ "$base_url?name=$name"
134+ fi
135+ done
136+
137+ - name : Show final assets on release (sanity)
138+ run : ls -la bin || true
139+
140+ - name : Clean build artifacts
141+ run : make clean
0 commit comments