ci: grant release job contents:write (fix 403 on publish) #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: build | |
| # Build the component across an arch matrix and attach the shipping artifacts | |
| # (plus the Pawn include) to GitHub releases. | |
| # | |
| # open.mp servers + components are currently 32-bit (i386), so the 32-bit | |
| # Windows/Linux artifacts are what ship today. The 64-bit jobs are | |
| # FUTURE-PROOFING for a 64-bit open.mp server — they build and upload artifacts | |
| # but are not the canonical release targets yet. | |
| # | |
| # Naming: <os>-<bits> e.g. windows-32, linux-64. macOS has no 32-bit support at | |
| # all (Apple removed it in Catalina), and there is no macOS open.mp server, so | |
| # macOS is a single 64-bit dev build-gate only (never shipped). | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| # ========================================================================= | |
| # 32-bit — the current shipping targets | |
| # ========================================================================= | |
| # --- Windows 32-bit .dll (MSVC) ------------------------------------------ | |
| # Native MSVC (the canonical open.mp component ABI). MariaDB Connector/C | |
| # submodule built from source (OpenSSL TLS, via vcpkg), statically linked -> | |
| # the .dll ships beside the bundled libssl/libcrypto OpenSSL runtime DLLs. | |
| windows-32: | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: x86 | |
| - name: Install OpenSSL (x86) via vcpkg | |
| shell: bash | |
| run: vcpkg install openssl:x86-windows | |
| - name: Configure (Win32 / MSVC, OpenSSL) | |
| shell: bash | |
| run: > | |
| cmake -B build-win32 -A Win32 -DCMAKE_BUILD_TYPE=Release | |
| "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| -DVCPKG_TARGET_TRIPLET=x86-windows | |
| - name: Build | |
| run: cmake --build build-win32 --config Release | |
| - name: Locate artifacts (.dll + bundled OpenSSL runtime DLLs) | |
| shell: bash | |
| run: | | |
| dll=$(find build-win32 -name omp-mysql.dll | head -1) | |
| test -n "$dll"; cp "$dll" omp-mysql.dll | |
| cp "$VCPKG_INSTALLATION_ROOT"/installed/x86-windows/bin/libssl-3*.dll . 2>/dev/null || true | |
| cp "$VCPKG_INSTALLATION_ROOT"/installed/x86-windows/bin/libcrypto-3*.dll . 2>/dev/null || true | |
| ls -la *.dll | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mysql-windows-x86 | |
| path: | | |
| omp-mysql.dll | |
| libssl-3*.dll | |
| libcrypto-3*.dll | |
| include/omp-mysql.inc | |
| # --- Linux 32-bit .so ----------------------------------------------------- | |
| # i386 Debian bullseye container (glibc 2.31, matching the server); MariaDB | |
| # Connector/C built from source (OpenSSL TLS), statically linked. | |
| linux-32: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Build 32-bit omp-mysql.so | |
| run: ARCH=32 ./scripts/build-linux.sh | |
| - name: Sanity-check artifact | |
| run: | | |
| test -f build-linux/omp-mysql.so | |
| file build-linux/omp-mysql.so | grep -q "ELF 32-bit" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mysql-linux-x86 | |
| path: | | |
| build-linux/omp-mysql.so | |
| include/omp-mysql.inc | |
| # ========================================================================= | |
| # 64-bit — future-proofing (a 64-bit open.mp server is not shipping yet) | |
| # ========================================================================= | |
| # --- Windows 64-bit .dll (MSVC) ------------------------------------------ | |
| windows-64: | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: x64 | |
| - name: Install OpenSSL (x64) via vcpkg | |
| shell: bash | |
| run: vcpkg install openssl:x64-windows | |
| - name: Configure (x64 / MSVC, OpenSSL) | |
| shell: bash | |
| run: > | |
| cmake -B build-win64 -A x64 -DCMAKE_BUILD_TYPE=Release | |
| "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| -DVCPKG_TARGET_TRIPLET=x64-windows | |
| - name: Build | |
| run: cmake --build build-win64 --config Release | |
| - name: Locate artifacts (.dll + bundled OpenSSL runtime DLLs) | |
| shell: bash | |
| run: | | |
| dll=$(find build-win64 -name omp-mysql.dll | head -1) | |
| test -n "$dll"; cp "$dll" omp-mysql.dll | |
| cp "$VCPKG_INSTALLATION_ROOT"/installed/x64-windows/bin/libssl-3*.dll . 2>/dev/null || true | |
| cp "$VCPKG_INSTALLATION_ROOT"/installed/x64-windows/bin/libcrypto-3*.dll . 2>/dev/null || true | |
| ls -la *.dll | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mysql-windows-x64 | |
| path: | | |
| omp-mysql.dll | |
| libssl-3*.dll | |
| libcrypto-3*.dll | |
| include/omp-mysql.inc | |
| # --- Linux 64-bit .so ----------------------------------------------------- | |
| linux-64: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Build 64-bit omp-mysql.so | |
| run: ARCH=64 ./scripts/build-linux.sh | |
| - name: Sanity-check artifact | |
| run: | | |
| test -f build-linux64/omp-mysql.so | |
| file build-linux64/omp-mysql.so | grep -q "ELF 64-bit" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mysql-linux-x64 | |
| path: | | |
| build-linux64/omp-mysql.so | |
| include/omp-mysql.inc | |
| # --- macOS .dylib (arm64) ------------------------------------------------- | |
| # A native macOS open.mp server now exists (Mac-Andreas/omp-server-macos), so | |
| # the .dylib is a real shipping target. That server is Apple Silicon (arm64) | |
| # only, and macOS has no 32-bit support at all (Apple removed it in Catalina), | |
| # so this builds arm64 to match. macos-latest runners are Apple Silicon, so | |
| # this builds natively (no cross-compile). | |
| macos-arm64: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Install connector build deps (OpenSSL/zstd for MariaDB Connector/C) | |
| run: brew install openssl@3 zstd | |
| - name: Configure | |
| run: > | |
| cmake -B build -DCMAKE_BUILD_TYPE=Release | |
| -DCMAKE_OSX_ARCHITECTURES=arm64 | |
| - name: Build | |
| run: cmake --build build --config Release | |
| - name: Bundle OpenSSL beside the .dylib (self-contained, like the Windows DLL) | |
| # The connector links Homebrew's OpenSSL via an absolute /opt/homebrew | |
| # path, which only exists on a Mac with Homebrew. To make a downloadable | |
| # artifact, copy libssl/libcrypto next to omp-mysql.dylib and rewrite all | |
| # the load paths (the component's refs, each lib's own id, and libssl's | |
| # internal libcrypto ref) to @loader_path so the trio is relocatable. | |
| # Editing load commands invalidates the ad-hoc code signature, so we | |
| # re-sign — required for the .dylib to load on Apple Silicon. | |
| run: | | |
| set -euo pipefail | |
| dylib=$(find build -name omp-mysql.dylib | head -1) | |
| test -n "$dylib" | |
| cp "$dylib" omp-mysql.dylib | |
| file omp-mysql.dylib | grep -q "arm64" | |
| ssl=$(otool -L omp-mysql.dylib | awk '/libssl/{print $1}') | |
| crypto=$(otool -L omp-mysql.dylib | awk '/libcrypto/{print $1}') | |
| cp -L "$ssl" libssl.3.dylib | |
| cp -L "$crypto" libcrypto.3.dylib | |
| chmod u+w omp-mysql.dylib libssl.3.dylib libcrypto.3.dylib | |
| # 1. component -> bundled OpenSSL | |
| install_name_tool -change "$ssl" @loader_path/libssl.3.dylib omp-mysql.dylib | |
| install_name_tool -change "$crypto" @loader_path/libcrypto.3.dylib omp-mysql.dylib | |
| # 2. each bundled lib's own id | |
| install_name_tool -id @loader_path/libssl.3.dylib libssl.3.dylib | |
| install_name_tool -id @loader_path/libcrypto.3.dylib libcrypto.3.dylib | |
| # 3. libssl's internal libcrypto ref (a Cellar path, distinct from above) | |
| ssl_crypto=$(otool -L libssl.3.dylib | awk '/libcrypto/{print $1}') | |
| install_name_tool -change "$ssl_crypto" @loader_path/libcrypto.3.dylib libssl.3.dylib | |
| # Re-sign ad-hoc (load-command edits invalidate the signature) | |
| for f in libcrypto.3.dylib libssl.3.dylib omp-mysql.dylib; do | |
| codesign --remove-signature "$f" 2>/dev/null || true | |
| codesign -s - -f "$f" | |
| done | |
| # Fail the build if any Homebrew path survived in any of the three | |
| if otool -L omp-mysql.dylib libssl.3.dylib libcrypto.3.dylib | grep -q /opt/homebrew; then | |
| echo "ERROR: a Homebrew path remains; bundle is not self-contained"; exit 1 | |
| fi | |
| otool -L omp-mysql.dylib | |
| - name: Verify the bundle loads with no Homebrew present | |
| # dlopen in a sanitized env (no DYLD_*, minimal PATH) proves @loader_path | |
| # resolves and the open.mp entry point is exported — i.e. it would load | |
| # on a clean Mac without Homebrew OpenSSL. | |
| run: | | |
| set -euo pipefail | |
| cat > /tmp/loadtest.c <<'EOF' | |
| #include <dlfcn.h> | |
| #include <stdio.h> | |
| int main(int argc, char** argv){ | |
| void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL); | |
| if(!h){ printf("DLOPEN FAILED: %s\n", dlerror()); return 1; } | |
| return dlsym(h, "ComponentEntryPoint") ? 0 : 2; | |
| } | |
| EOF | |
| clang -arch arm64 /tmp/loadtest.c -o /tmp/loadtest | |
| env -i PATH=/usr/bin:/bin /tmp/loadtest "$PWD/omp-mysql.dylib" | |
| echo "macOS bundle loads cleanly and exports ComponentEntryPoint" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: mysql-macos-arm64 | |
| path: | | |
| omp-mysql.dylib | |
| libssl.3.dylib | |
| libcrypto.3.dylib | |
| include/omp-mysql.inc | |
| # ========================================================================= | |
| # Release: attach all built artifacts on a tag | |
| # ========================================================================= | |
| # Hard-gated on the canonical 32-bit Win/Linux targets plus macOS arm64 — a | |
| # release won't publish unless all three built. The 64-bit artifacts are still | |
| # included opportunistically if their jobs succeeded. | |
| release: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [windows-32, linux-32, macos-arm64] | |
| runs-on: ubuntu-latest | |
| # The default GITHUB_TOKEN is read-only, so action-gh-release got a 403 | |
| # ("Resource not accessible by integration") when creating the release. | |
| # Grant this job write access to repo contents (releases) — least-privilege, | |
| # scoped to just the publishing job. | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| - name: Package per-target archives | |
| run: | | |
| cd dist | |
| for d in */; do | |
| name="${d%/}" | |
| (cd "$d" && zip -r "../${name}.zip" .) | |
| done | |
| ls -la | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| files: dist/*.zip | |
| generate_release_notes: true |