11name : Release
22
3- # Builds self-contained binaries for every supported platform and publishes
3+ # Builds self-contained binaries for every platform and publishes
44# them to a GitHub Release. Trigger by pushing a version tag:
55#
66# git tag v1.0.0 && git push origin v1.0.0
1313 push :
1414 tags :
1515 - " v*"
16- workflow_dispatch :
1716
1817permissions :
1918 contents : write
@@ -26,90 +25,141 @@ jobs:
2625 fail-fast : false
2726 matrix :
2827 include :
29- - os : macos-14
30- target : aarch64-apple-darwin
31- # NOTE: Intel macOS (x86_64-apple-darwin) is temporarily omitted —
32- # GitHub's macos-13 Intel runners are being deprecated and queue
33- # unpredictably. Intel users can build from source for now; a
34- # cross-compiled Intel binary will be added in a follow-up.
35- - os : ubuntu-22.04
28+ - os : macos-latest
29+ target : x86_64-apple-darwin
30+ - os : ubuntu-latest
3631 target : x86_64-unknown-linux-gnu
37- - os : ubuntu-22.04-arm
38- target : aarch64-unknown-linux-gnu
39- - os : windows-2022
32+ - os : windows-latest
4033 target : x86_64-pc-windows-gnu
4134
4235 steps :
4336 - uses : actions/checkout@v4
4437
45- # ── macOS: static-link Homebrew OpenSSL ──────────────────────
46- - name : Build (macOS)
47- if : runner.os == 'macOS'
48- run : |
49- brew install openssl@3
50- make STATIC_SSL=1 OPENSSL_DIR="$(brew --prefix openssl@3)"
51- ./build/qs version
52-
53- # ── Linux: static-link distro OpenSSL ────────────────────────
54- - name : Build (Linux)
38+ # ── Dependencies ─────────────────────────────────────────────
39+ - name : Install OpenSSL (Linux)
5540 if : runner.os == 'Linux'
5641 run : |
5742 sudo apt-get update
5843 sudo apt-get install -y libssl-dev
59- make SSL_LIBS="-l:libssl.a -l:libcrypto.a"
60- ./build/qs version
6144
62- # ── Windows: MSYS2 / UCRT64, static-link OpenSSL ─────────────
63- - name : Set up MSYS2
45+ - name : Install OpenSSL (macOS)
46+ if : runner.os == 'macOS'
47+ run : brew install openssl@3
48+
49+ - name : Setup MSYS2 (Windows)
6450 if : runner.os == 'Windows'
6551 uses : msys2/setup-msys2@v2
6652 with :
67- msystem : UCRT64
53+ msystem : MINGW64
6854 update : true
6955 install : >-
56+ mingw-w64-x86_64-gcc
57+ mingw-w64-x86_64-openssl
58+ mingw-w64-x86_64-pkgconf
7059 make
71- mingw-w64-ucrt-x86_64-gcc
72- mingw-w64-ucrt-x86_64-openssl
60+
61+ # ── Build (statically linked) ───────────────────────────────
62+ - name : Build (macOS)
63+ if : runner.os == 'macOS'
64+ run : make STATIC_SSL=1 OPENSSL_DIR="$(brew --prefix openssl@3)"
65+
66+ - name : Build (Linux)
67+ if : runner.os == 'Linux'
68+ run : make SSL_LIBS="-l:libssl.a -l:libcrypto.a"
7369
7470 - name : Build (Windows)
7571 if : runner.os == 'Windows'
7672 shell : msys2 {0}
73+ run : make SSL_LIBS="/mingw64/lib/libssl.a /mingw64/lib/libcrypto.a"
74+
75+ # ── Verify ───────────────────────────────────────────────────
76+ - name : Verify binary (Linux / macOS)
77+ if : runner.os != 'Windows'
78+ run : ./build/qs version
79+
80+ - name : Verify binary (Windows)
81+ if : runner.os == 'Windows'
82+ shell : msys2 {0}
83+ run : ./build/qs.exe version
84+
85+ - name : Check binary dependencies (Linux)
86+ if : runner.os == 'Linux'
7787 run : |
78- make SSL_LIBS="/ucrt64/lib/libssl.a /ucrt64/lib/libcrypto.a"
79- ./build/qs.exe version
88+ echo "=== Dynamic library dependencies ==="
89+ ldd build/qs
90+ echo ""
91+ echo "=== Checking for libssl/libcrypto ==="
92+ if ldd build/qs | grep -qi 'ssl\|crypto'; then
93+ echo "WARNING: binary dynamically links OpenSSL"
94+ exit 1
95+ else
96+ echo "OK: binary is self-contained (no OpenSSL dynamic deps)"
97+ fi
98+
99+ - name : Check binary dependencies (macOS)
100+ if : runner.os == 'macOS'
101+ run : |
102+ echo "=== Dynamic library dependencies ==="
103+ otool -L build/qs
104+ echo ""
105+ echo "=== Checking for OpenSSL dylib ==="
106+ if otool -L build/qs | grep -qi 'openssl\|libssl\|libcrypto'; then
107+ echo "WARNING: binary dynamically links OpenSSL"
108+ exit 1
109+ else
110+ echo "OK: binary is self-contained (no OpenSSL dynamic deps)"
111+ fi
112+
113+ - name : Check binary dependencies (Windows)
114+ if : runner.os == 'Windows'
115+ shell : msys2 {0}
116+ run : |
117+ echo "=== Dynamic library dependencies ==="
118+ objdump -p build/qs.exe | grep "DLL Name" || true
119+ echo ""
120+ echo "=== Checking for OpenSSL DLLs ==="
121+ if objdump -p build/qs.exe | grep -qi 'ssl\|crypto'; then
122+ echo "WARNING: binary dynamically links OpenSSL"
123+ exit 1
124+ else
125+ echo "OK: binary is self-contained (no OpenSSL dynamic deps)"
126+ fi
80127
81128 # ── Package ──────────────────────────────────────────────────
82- - name : Package
129+ - name : Create release archive
83130 shell : bash
84131 run : |
85132 set -eu
133+
86134 VERSION="${GITHUB_REF_NAME#v}"
87- case "$VERSION" in refs/*|"") VERSION="dev" ;; esac
88135 PKG="quantoscript-${VERSION}-${{ matrix.target }}"
89- mkdir -p "dist/$PKG/bin" "dist/$PKG/stdlib" "dist/$PKG/examples"
90136
91- if [ "${{ runner.os }}" = "Windows" ]; then BIN="build/qs.exe"; else BIN="build/qs"; fi
92- cp "$BIN" "dist/$PKG/bin/"
93- cp stdlib/*.qs "dist/$PKG/stdlib/"
94- cp examples/*.qs "dist/$PKG/examples/"
95- cp README.md CHANGELOG.md LICENSE "dist/$PKG/"
137+ # Assemble package tree
138+ mkdir -p "dist/$PKG/bin"
139+ if [ "${{ runner.os }}" = "Windows" ]; then
140+ cp build/qs.exe "dist/$PKG/bin/qs.exe"
141+ else
142+ cp build/qs "dist/$PKG/bin/qs"
143+ fi
144+ cp -R stdlib "dist/$PKG/stdlib"
145+ cp -R examples "dist/$PKG/examples"
146+ cp LICENSE README.md "dist/$PKG/"
96147
148+ # Create archive
97149 cd dist
98150 if [ "${{ runner.os }}" = "Windows" ]; then
99151 7z a "${PKG}.zip" "$PKG" >/dev/null
100- certutil -hashfile "${PKG}.zip" SHA256 | sed -n '2p' | tr -d ' \r' > "${PKG}.zip.sha256.tmp"
101- echo "$(cat ${PKG}.zip.sha256.tmp) ${PKG}.zip" > "${PKG}.zip.sha256"
102- rm -f "${PKG}.zip.sha256.tmp"
103152 else
104153 tar czf "${PKG}.tar.gz" "$PKG"
105- if command -v sha256sum >/dev/null 2>&1; then
106- sha256sum "${PKG}.tar.gz" > "${PKG}.tar.gz.sha256"
107- else
108- shasum -a 256 "${PKG}.tar.gz" > "${PKG}.tar.gz.sha256"
109- fi
110154 fi
155+
156+ # Generate SHA256 checksum (sha256sum is available on all runners)
157+ ASSET=$(ls "${PKG}.tar.gz" "${PKG}.zip" 2>/dev/null | head -1)
158+ sha256sum "$ASSET" > "${ASSET}.sha256"
159+ echo "=== Packaged ==="
111160 ls -la
112161
162+ # ── Upload artifacts ─────────────────────────────────────────
113163 - name : Upload build artifacts
114164 uses : actions/upload-artifact@v4
115165 with :
@@ -124,24 +174,24 @@ jobs:
124174 name : Publish release
125175 needs : build
126176 runs-on : ubuntu-latest
127- # Publish even if some platform legs failed, so a release still ships with
128- # whatever binaries built successfully. Only runs for tag pushes.
129- if : always() && startsWith(github.ref, 'refs/tags/')
177+ if : startsWith(github.ref, 'refs/tags/')
130178 steps :
131179 - name : Download all artifacts
132180 uses : actions/download-artifact@v4
133181 with :
134182 path : dist
135183 merge-multiple : true
136184
137- - name : Combine checksums
185+ - name : List release assets
138186 run : |
139- cd dist
140- cat *.sha256 > SHA256SUMS.txt 2>/dev/null || true
141- echo "=== artifacts ==="
142- ls -la
143- echo "=== SHA256SUMS.txt ==="
144- cat SHA256SUMS.txt 2>/dev/null || echo "(none)"
187+ echo "=== All release assets ==="
188+ ls -la dist/
189+ echo ""
190+ echo "=== SHA256 checksums ==="
191+ for f in dist/*.sha256; do
192+ echo "--- $f ---"
193+ cat "$f"
194+ done
145195
146196 - name : Fail if nothing built
147197 run : |
@@ -157,4 +207,4 @@ jobs:
157207 files : |
158208 dist/*.tar.gz
159209 dist/*.zip
160- dist/SHA256SUMS.txt
210+ dist/*.sha256
0 commit comments