Build OpenSSL 4.0.0-beta1 via workflow_dispatch #228
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 OpenSSL | |
| run-name: Build OpenSSL ${{ inputs.version }} via ${{ github.event_name }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| build_type: | |
| description: 'Build Source: OpenSSL Release or OpenSSL Branch/OpenSSL fork' | |
| required: true | |
| type: choice | |
| options: | |
| - release | |
| - branch | |
| default: release | |
| version: | |
| description: 'OpenSSL Release Version, OpenSSL Branch Name or OpenSSL Fork Repo(e.g. 3.4.0, master, or user/repo/branch)' | |
| required: true | |
| type: string | |
| ignore_eol: | |
| description: 'Ignore EOL Check' | |
| required: false | |
| type: boolean | |
| default: false | |
| keep_raw_artifacts: | |
| description: 'Keep raw build artifacts' | |
| required: false | |
| type: boolean | |
| default: false | |
| workflow_call: | |
| inputs: | |
| build_type: | |
| required: false | |
| type: string | |
| default: release | |
| version: | |
| required: true | |
| type: string | |
| ignore_eol: | |
| required: false | |
| type: boolean | |
| default: false | |
| keep_raw_artifacts: | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| # ========================================================================= | |
| # 0. VALIDATE VERSION & EOL | |
| # ========================================================================= | |
| validate-version: | |
| name: Validate Inputs | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: write | |
| outputs: | |
| version: ${{ steps.check.outputs.version }} | |
| target_repo: ${{ steps.check.outputs.target_repo }} | |
| ref: ${{ steps.check.outputs.ref }} | |
| sha: ${{ steps.check.outputs.sha }} | |
| artifact_version: ${{ steps.check.outputs.artifact_version }} | |
| slugified_version: ${{ steps.check.outputs.slugified_version }} | |
| is_fork: ${{ steps.check.outputs.is_fork }} | |
| steps: | |
| - name: Check EOL or Branch Existence | |
| id: check | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| BUILD_TYPE="${{ inputs.build_type }}" | |
| IGNORE_EOL="${{ inputs.ignore_eol }}" | |
| TARGET_REPO="openssl/openssl" | |
| IS_FORK="false" | |
| if [ "$BUILD_TYPE" == "release" ]; then | |
| MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2) | |
| EOL_DATE=$(curl -s https://endoflife.date/api/openssl.json | jq -r ".[] | select(.cycle == \"$MAJOR_MINOR\") | .eol") | |
| if [ -z "$EOL_DATE" ] || [ "$EOL_DATE" == "null" ]; then | |
| echo "⚠️ Could not determine EOL date for $MAJOR_MINOR. Proceeding cautiously." | |
| else | |
| TODAY=$(date +%Y-%m-%d) | |
| if [[ "$TODAY" > "$EOL_DATE" ]]; then | |
| echo "❌ OpenSSL $MAJOR_MINOR reached EOL on $EOL_DATE." | |
| if [ "$IGNORE_EOL" != "true" ]; then | |
| echo "Aborting build. Check 'Ignore EOL' to override." | |
| exit 1 | |
| fi | |
| echo "⚠️ Ignore EOL is checked. Proceeding anyway." | |
| fi | |
| fi | |
| TARGET_REF="openssl-$VERSION" | |
| echo "🔍 Resolving SHA for tag '$TARGET_REF'..." | |
| SHA=$(git ls-remote --tags https://github.com/$TARGET_REPO.git "$TARGET_REF" | awk '{print $1}') | |
| if [ -z "$SHA" ]; then | |
| echo "❌ Tag '$TARGET_REF' not found in $TARGET_REPO." | |
| exit 1 | |
| fi | |
| ARTIFACT_VERSION="$VERSION" | |
| SLUGIFIED_VERSION="$VERSION" | |
| else | |
| # Branch Mode | |
| if [[ "$VERSION" == */*/* ]]; then | |
| # Format: user/repo/branch | |
| TARGET_REPO=$(echo "$VERSION" | cut -d'/' -f1,2) | |
| TARGET_REF=$(echo "$VERSION" | cut -d'/' -f3-) | |
| IS_FORK="true" | |
| else | |
| TARGET_REF="$VERSION" | |
| fi | |
| echo "🔍 Resolving SHA for branch/ref '$TARGET_REF' in repository '$TARGET_REPO'..." | |
| SHA=$(git ls-remote https://github.com/$TARGET_REPO.git "$TARGET_REF" | awk '{print $1}') | |
| if [ -z "$SHA" ]; then | |
| # Check if it's already a SHA | |
| if [[ "$TARGET_REF" =~ ^[0-9a-f]{40}$ ]]; then | |
| SHA="$TARGET_REF" | |
| else | |
| echo "❌ Reference '$TARGET_REF' does not exist in $TARGET_REPO." | |
| exit 1 | |
| fi | |
| fi | |
| TIMESTAMP=$(date -u +%Y%m%dT%H%M%SZ) | |
| # Slugify the whole version input (e.g. user/repo/branch -> user_repo_branch) | |
| SLUGIFIED_VERSION=$(echo "$VERSION" | sed 's/\//_/g') | |
| # Truncate for filename safety | |
| SAFE_PART=$(echo "$SLUGIFIED_VERSION" | cut -c 1-100) | |
| ARTIFACT_VERSION="${SAFE_PART}_${TIMESTAMP}" | |
| fi | |
| # Output resolved information | |
| echo "target_repo=$TARGET_REPO" >> $GITHUB_OUTPUT | |
| echo "is_fork=$IS_FORK" >> $GITHUB_OUTPUT | |
| echo "ref=$TARGET_REF" >> $GITHUB_OUTPUT | |
| echo "sha=$SHA" >> $GITHUB_OUTPUT | |
| echo "artifact_version=$ARTIFACT_VERSION" >> $GITHUB_OUTPUT | |
| echo "slugified_version=$SLUGIFIED_VERSION" >> $GITHUB_OUTPUT | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| # ========================================================================= | |
| # 1. BUILD COMMON ASSETS (Headers & Docs) | |
| # ========================================================================= | |
| build-common-assets: | |
| name: Build Headers & Docs | |
| needs: validate-version | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| repository: ${{ needs.validate-version.outputs.target_repo }} | |
| ref: ${{ needs.validate-version.outputs.sha }} | |
| - name: Build Common Assets | |
| run: | | |
| ./Configure linux-x86_64 no-tests --prefix=/usr/local | |
| make -j$(nproc) install_dev DESTDIR=$PWD/common-assets | |
| make install_html_docs DESTDIR=$PWD/common-assets || true | |
| # Include License | |
| cp LICENSE.txt common-assets/usr/local/ | |
| # --- Generate README --- | |
| cat << 'EOF' > common-assets/usr/local/README.txt | |
| OpenSSL Distribution Package | |
| ============================ | |
| This package contains the OpenSSL executable, shared libraries, static libraries (stripped), C headers, and documentation. | |
| Package Layout: | |
| --------------- | |
| * version.txt - OpenSSL version in this package [non-redistributable] | |
| * openssl - The OpenSSL command-line utility [redistributable/optional] | |
| * libcrypto / libssl - Shared libraries [redistributable/required] | |
| * install_symlinks.sh - (POSIX only) Script to restore shared library symlinks [redistributable/optional] | |
| * engines/ - OpenSSL engines [redistributable/optional] | |
| * providers/ - OpenSSL providers [redistributable/optional] | |
| * doc/ - Developers Documentation [non-redistributable] | |
| * include/ - C Header files [non-redistributable] | |
| * lib/import/ - Import libraries (Windows only) [non-redistributable] | |
| * lib/static/ - Static libraries (.lib / .a) [non-redistributable] | |
| Linking Instructions: | |
| --------------------- | |
| * Windows Dynamic: Link against the import libraries in `lib/import/` (which point to the DLLs in the root). | |
| * Windows Static: Link against the static libraries in `lib/static/` (Compiled with /MD Dynamic CRT). | |
| * POSIX Dynamic: Link directly against the shared libraries (.so / .dylib) in the root directory. | |
| * POSIX Static: Link against the static archives (.a) in `lib/static/`. | |
| Deployment Instructions (Linux / macOS / Unix): | |
| ----------------------------------------------- | |
| Windows file systems fail to extract Unix symbolic links. To ensure cross-platform compatibility, this archive contains only the physical shared library files. | |
| If this package includes the 'install_symlinks.sh' script, you MUST run it from the root of the extracted directory to recreate the required library symlinks (e.g., libcrypto.so -> libcrypto.so.X). | |
| $ cd <extracted_directory> | |
| $ sh ./install_symlinks.sh | |
| Windows Users: | |
| -------------- | |
| Windows does not use symlinks for OpenSSL DLLs. You can safely ignore or delete the shell script. | |
| EOF | |
| # Remove unnecessary large directories | |
| rm -rf common-assets/usr/local/lib common-assets/usr/local/lib64 common-assets/usr/local/bin common-assets/usr/local/ssl | |
| - name: Upload Common Assets | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: openssl-common-assets | |
| path: common-assets/usr/local | |
| retention-days: 1 | |
| # ========================================================================= | |
| # 2. COMPILE BINARIES (Fan-Out Matrix) | |
| # ========================================================================= | |
| compile-binaries: | |
| name: Compile (${{ matrix.platform.label }} ${{ matrix.platform.arch }} ${{ matrix.linkage }}) | |
| needs: validate-version | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| linkage: [shared, static] | |
| platform: | |
| - { label: Windows, os: windows-latest, arch: x64, target: VC-WIN64A, vcvars: amd64 } | |
| - { label: Windows, os: windows-latest, arch: x86, target: VC-WIN32, vcvars: x86 } | |
| # - { label: Windows, os: windows-latest, arch: arm64, target: VC-WIN64-ARM, vcvars: amd64_arm64 } # ARM64 build is currently disabled due possible confusion with ARM64EC | |
| - { label: Windows, os: windows-latest, arch: arm64ec, target: VC-WIN64-ARM, vcvars: amd64_arm64 } | |
| - { label: Linux, os: ubuntu-latest, arch: x64, target: linux-x86_64 } | |
| - { label: Linux, os: ubuntu-latest, arch: arm64, target: linux-aarch64 } | |
| - { label: macOS, os: macos-14, arch: x64, target: darwin64-x86_64-cc, minos: "10.14" } | |
| - { label: macOS, os: macos-14, arch: arm64, target: darwin64-arm64-cc, minos: "11.0" } | |
| # - { label: Android, os: ubuntu-latest, arch: x64, target: android-x86_64, api: 21 } # Android x64 build is currently disabled as Delphi is not supporting Android x86 builds | |
| - { label: Android, os: ubuntu-latest, arch: arm64, target: android-arm64, api: 21 } | |
| - { label: Android, os: ubuntu-latest, arch: arm, target: android-arm, api: 21 } | |
| - { label: iOS, os: macos-14, arch: arm64, target: ios64-cross } | |
| - { label: iOS, os: macos-14, arch: sim-arm64, target: iossimulator-xcrun, minos: "11.0" } | |
| # - { label: iOS, os: macos-14, arch: sim-x64, target: iossimulator-xcrun, minos: "10.14" } # iOS x64 simulator is currently disabled | |
| exclude: | |
| - linkage: shared | |
| platform: { label: iOS } # iOS is static only | |
| runs-on: ${{ matrix.platform.os }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| repository: ${{ needs.validate-version.outputs.target_repo }} | |
| ref: ${{ needs.validate-version.outputs.sha }} | |
| - name: Compile Windows (Standard) | |
| if: matrix.platform.label == 'Windows' && matrix.platform.arch != 'arm64ec' | |
| shell: cmd | |
| run: | | |
| call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform.vcvars }} | |
| set "PREFIX=%GITHUB_WORKSPACE%\raw_artifact\usr\local" | |
| set "TARGET=${{ matrix.platform.target }}" | |
| :: --- SHARED BUILD --- | |
| if "${{ matrix.linkage }}"=="shared" ( | |
| perl Configure %TARGET% --prefix="%PREFIX%" shared no-tests -D_WIN32_WINNT=0x0A00 | |
| ) | |
| :: --- STATIC BUILD --- | |
| if "${{ matrix.linkage }}"=="static" ( | |
| perl Configure %TARGET% --prefix="%PREFIX%" no-shared no-apps no-module no-tests "CFLAGS=/MD -D_WIN32_WINNT=0x0A00" || perl Configure %TARGET% --prefix="%PREFIX%" no-shared no-module no-tests "CFLAGS=/MD -D_WIN32_WINNT=0x0A00" | |
| ) | |
| nmake && nmake install_sw | |
| - name: Compile Windows (ARM64EC) | |
| if: matrix.platform.label == 'Windows' && matrix.platform.arch == 'arm64ec' | |
| shell: cmd | |
| run: | | |
| call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform.vcvars }} | |
| set "PREFIX=%GITHUB_WORKSPACE%\raw_artifact\usr\local" | |
| set "TARGET=${{ matrix.platform.target }}" | |
| :: --- SHARED BUILD --- | |
| if "${{ matrix.linkage }}"=="shared" ( | |
| perl Configure %TARGET% --prefix="%PREFIX%" shared no-tests no-asm "CFLAGS=/nologo /arm64EC /O1 /Zi /D_WIN32_WINNT=0x0A00" "LDFLAGS=/MACHINE:ARM64EC /DEBUG" "ARFLAGS=/MACHINE:ARM64EC" | |
| ) | |
| :: --- STATIC BUILD --- | |
| if "${{ matrix.linkage }}"=="static" ( | |
| perl Configure %TARGET% --prefix="%PREFIX%" no-shared no-apps no-module no-tests no-asm "CFLAGS=/nologo /arm64EC /O1 /Zi /D_WIN32_WINNT=0x0A00 /MD" "LDFLAGS=/MACHINE:ARM64EC /DEBUG" "ARFLAGS=/MACHINE:ARM64EC" || perl Configure %TARGET% --prefix="%PREFIX%" no-shared no-module no-tests no-asm "CFLAGS=/nologo /arm64EC /O1 /Zi /D_WIN32_WINNT=0x0A00 /MD" "LDFLAGS=/MACHINE:ARM64EC /DEBUG" "ARFLAGS=/MACHINE:ARM64EC" | |
| ) | |
| nmake && nmake install_sw | |
| - name: Organize Windows Binaries | |
| if: matrix.platform.label == 'Windows' | |
| shell: cmd | |
| run: | | |
| set "PREFIX=%GITHUB_WORKSPACE%\raw_artifact\usr\local" | |
| mkdir raw_artifact\dist | |
| if "${{ matrix.linkage }}"=="shared" ( | |
| mkdir raw_artifact\dist\engines | |
| mkdir raw_artifact\dist\providers | |
| mkdir raw_artifact\dist\lib\import | |
| copy "%PREFIX%\bin\openssl.exe" raw_artifact\dist\ | |
| copy "%PREFIX%\bin\*.dll" raw_artifact\dist\ | |
| for /d %%d in ("%PREFIX%\lib\engines-*") do copy "%%d\*.dll" raw_artifact\dist\engines\ | |
| for /d %%d in ("%PREFIX%\lib\ossl-modules*") do copy "%%d\*.dll" raw_artifact\dist\providers\ | |
| copy "%PREFIX%\lib\*.lib" raw_artifact\dist\lib\import\ | |
| ) else ( | |
| mkdir raw_artifact\dist\lib\static | |
| copy "%PREFIX%\lib\*.lib" raw_artifact\dist\lib\static\ | |
| ) | |
| - name: Install Linux Dependencies | |
| if: matrix.platform.label == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libsctp-dev | |
| if [ "${{ matrix.platform.arch }}" == "arm64" ]; then | |
| sudo apt-get install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross | |
| fi | |
| - name: Compile Unix (POSIX) | |
| if: matrix.platform.label != 'Windows' | |
| shell: bash | |
| run: | | |
| TARGET="${{ matrix.platform.target }}" | |
| LINKAGE="${{ matrix.linkage }}" | |
| LABEL="${{ matrix.platform.label }}" | |
| PREFIX="${{ github.workspace }}/raw_artifact/usr/local" | |
| EXTRA_FLAGS="" | |
| # --- Platform Specific Setup --- | |
| if [ "$LABEL" == "macOS" ] ; then | |
| EXTRA_FLAGS="-mmacosx-version-min=${{ matrix.platform.minos }}" | |
| elif [ "$LABEL" == "Linux" ]; then | |
| EXTRA_FLAGS="enable-sctp -Wl,-rpath,'\$\$ORIGIN'" | |
| if [ "$TARGET" == "linux-aarch64" ]; then | |
| export CROSS_COMPILE=aarch64-linux-gnu- | |
| fi | |
| elif [ "$LABEL" == "Android" ]; then | |
| sed -i 's/-fPIC/-fPIC -Wl,-z,max-page-size=16384/g' Configurations/15-android.conf | |
| export ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME | |
| export PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH | |
| elif [ "$LABEL" == "iOS" ]; then | |
| if [[ "$TARGET" == *"simulator"* ]]; then | |
| export CROSS_TOP=$(xcode-select -print-path)/Platforms/iPhoneSimulator.platform/Developer | |
| export CROSS_SDK=iPhoneSimulator.sdk | |
| EXTRA_FLAGS="-mios-simulator-version-min=${{ matrix.platform.minos }}" | |
| else | |
| export CROSS_TOP=$(xcode-select -print-path)/Platforms/iPhoneOS.platform/Developer | |
| export CROSS_SDK=iPhoneOS.sdk | |
| fi | |
| fi | |
| # --- Configure & Build --- | |
| if [ "$LINKAGE" == "shared" ]; then | |
| ./Configure $TARGET shared no-tests $EXTRA_FLAGS --prefix="$PREFIX" | |
| else | |
| if ! ./Configure $TARGET no-shared no-apps no-module no-tests $EXTRA_FLAGS --prefix="$PREFIX"; then | |
| ./Configure $TARGET no-shared no-module no-tests $EXTRA_FLAGS --prefix="$PREFIX" | |
| fi | |
| fi | |
| make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu) | |
| make install_sw DESTDIR="/" | |
| - name: Organize Unix Binaries | |
| if: matrix.platform.label != 'Windows' | |
| shell: bash | |
| run: | | |
| LABEL="${{ matrix.platform.label }}" | |
| LINKAGE="${{ matrix.linkage }}" | |
| PREFIX="${{ github.workspace }}/raw_artifact/usr/local" | |
| mkdir -p raw_artifact/dist/{engines,providers,lib/static} | |
| if [ "$LINKAGE" == "shared" ]; then | |
| # Executable | |
| find "$PREFIX/bin" -type f -name "openssl" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| # Shared Libs | |
| if [ "$LABEL" == "Android" ]; then | |
| find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "*.so" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| else | |
| # Versioned libs only: libcrypto.so.X, libssl.so.X or libcrypto.X.dylib, libssl.X.dylib | |
| find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "libcrypto.so.*" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "libssl.so.*" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "libcrypto.*.dylib" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "libssl.*.dylib" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true | |
| fi | |
| # Engines & Providers | |
| find "$PREFIX" -path "*/engines-*/*.so" -exec cp {} raw_artifact/dist/engines/ \; 2>/dev/null || true | |
| find "$PREFIX" -path "*/engines-*/*.dylib" -exec cp {} raw_artifact/dist/engines/ \; 2>/dev/null || true | |
| find "$PREFIX" -path "*/ossl-modules*/*.so" -exec cp {} raw_artifact/dist/providers/ \; 2>/dev/null || true | |
| find "$PREFIX" -path "*/ossl-modules*/*.dylib" -exec cp {} raw_artifact/dist/providers/ \; 2>/dev/null || true | |
| # Stripping (Non-macOS) | |
| if [ "$LABEL" != "macOS" ]; then | |
| find raw_artifact/dist -maxdepth 1 -type f \( -name "openssl" -o -name "*.so*" \) -exec strip {} + 2>/dev/null || true | |
| find raw_artifact/dist/engines raw_artifact/dist/providers -type f -name "*.so" -exec strip {} + 2>/dev/null || true | |
| fi | |
| # Symlinks script (Linux/macOS) | |
| if [ "$LABEL" == "Linux" ] || [ "$LABEL" == "macOS" ]; then | |
| echo "#!/bin/sh" > raw_artifact/dist/install_symlinks.sh | |
| echo "echo \"Restoring shared library symlinks...\"" >> raw_artifact/dist/install_symlinks.sh | |
| cd raw_artifact/dist | |
| for lib in libcrypto libssl; do | |
| if [ "$LABEL" == "Linux" ]; then | |
| REAL_FILE=$(ls ${lib}.so.* 2>/dev/null | head -n 1) | |
| if [ -n "$REAL_FILE" ]; then | |
| echo "ln -sf $REAL_FILE ${lib}.so" >> install_symlinks.sh | |
| fi | |
| else | |
| REAL_FILE=$(ls ${lib}.*.dylib 2>/dev/null | head -n 1) | |
| if [ -n "$REAL_FILE" ]; then | |
| echo "ln -sf $REAL_FILE ${lib}.dylib" >> install_symlinks.sh | |
| fi | |
| fi | |
| done | |
| chmod +x install_symlinks.sh | |
| cd - > /dev/null | |
| fi | |
| else | |
| # Static linkage | |
| mkdir -p raw_artifact/dist/lib/static | |
| find "$PREFIX" -type f -name "*.a" -exec cp {} raw_artifact/dist/lib/static/ \; 2>/dev/null || true | |
| # Stripping (Non-macOS) | |
| if [ "$LABEL" != "macOS" ]; then | |
| find raw_artifact/dist/lib/static -type f -name "*.a" -exec strip -S {} + 2>/dev/null || true | |
| fi | |
| fi | |
| find raw_artifact/dist -type d -empty -delete || true | |
| - name: Upload Raw Artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: raw-${{ matrix.platform.label }}-${{ matrix.platform.arch }}-${{ matrix.linkage }} | |
| path: raw_artifact/dist | |
| retention-days: 1 | |
| # ========================================================================= | |
| # 3. PACKAGE RELEASE (Fan-In Matrix) | |
| # ========================================================================= | |
| package-release: | |
| name: Package (${{ matrix.label }} ${{ matrix.arch }}) | |
| needs: [validate-version, build-common-assets, compile-binaries] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Windows packaging moved to ubuntu-latest for speed and native 'zip' support | |
| - { label: Windows, arch: x64, runner: ubuntu-latest } | |
| - { label: Windows, arch: x86, runner: ubuntu-latest } | |
| # - { label: Windows, arch: arm64, runner: ubuntu-latest } # Windows arm64 package is disabled | |
| - { label: Windows, arch: arm64ec, runner: ubuntu-latest } | |
| # Linux & Android | |
| - { label: Linux, arch: x64, runner: ubuntu-latest } | |
| - { label: Linux, arch: arm64, runner: ubuntu-latest } | |
| # - { label: Android, arch: x64, runner: ubuntu-latest } # Android x64 package is disabled | |
| - { label: Android, arch: arm64, runner: ubuntu-latest } | |
| - { label: Android, arch: arm, runner: ubuntu-latest } | |
| # Apple platforms MUST use macOS runners for lipo, otool, install_name_tool, and Apple strip | |
| - { label: macOS, arch: universal, runner: macos-14 } | |
| - { label: iOS, arch: arm64, runner: macos-14 } | |
| - { label: iOS, arch: sim-arm64, runner: macos-14 } | |
| # - { label: iOS, arch: sim-x64, runner: macos-14 } #iOS x64 simulator package is disabled | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download Common Assets | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: openssl-common-assets | |
| path: common-assets | |
| - name: Download Raw Binaries (Standard) | |
| if: matrix.label != 'macOS' | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: raw-${{ matrix.label }}-${{ matrix.arch }}-* | |
| path: raw-binaries | |
| merge-multiple: false | |
| - name: Download Raw Binaries (macOS Universal) | |
| if: matrix.label == 'macOS' | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: raw-macOS-* | |
| path: raw-binaries | |
| merge-multiple: false | |
| - name: Merge Binaries and Assets | |
| if: matrix.label != 'macOS' | |
| shell: bash | |
| run: | | |
| # Merge contents of downloaded raw artifacts into dist/ | |
| # Standard behavior: download-artifact creates subdirectories named after artifacts. | |
| # Flattened behavior: If only one artifact exists, it may be extracted directly. | |
| HAS_RAW_SUBDIRS=false | |
| for d in raw-binaries/raw-*/; do | |
| if [ -d "$d" ]; then | |
| HAS_RAW_SUBDIRS=true | |
| break | |
| fi | |
| done | |
| if [ "$HAS_RAW_SUBDIRS" = true ]; then | |
| echo "Detected nested artifact structure. Merging subdirectories..." | |
| for d in raw-binaries/raw-*/; do | |
| if [ -d "$d" ]; then | |
| echo "Merging $d contents into dist/" | |
| cp -R "$d". dist/ | |
| fi | |
| done | |
| else | |
| echo "Detected flattened artifact structure. Merging raw-binaries/ directly..." | |
| cp -R raw-binaries/. dist/ | |
| fi | |
| - name: Organize & Lipo (macOS Universal) | |
| if: matrix.label == 'macOS' | |
| shell: bash | |
| run: | | |
| # 1. Relocate and Strip individual architectures | |
| for arch in x64 arm64; do | |
| BASE_DIR="raw-binaries/raw-macOS-$arch-shared" | |
| find "$BASE_DIR" -type f \( -name "*.dylib" -o -name "*.so" -o -name "openssl" \) | while read -r target_file; do | |
| if [[ "$target_file" == *"openssl" ]]; then | |
| strip "$target_file" || true | |
| else | |
| strip -x "$target_file" || true | |
| fi | |
| if [[ "$target_file" == *".dylib" ]]; then | |
| install_name_tool -id "@rpath/$(basename "$target_file")" "$target_file" || true | |
| fi | |
| DEPS=$(otool -L "$target_file" 2>/dev/null | awk '/\/usr\/local\/lib\/lib/ {print $1}') | |
| for dep in $DEPS; do | |
| depname=$(basename "$dep") | |
| if [[ "$target_file" == *"engines"* ]] || [[ "$target_file" == *"providers"* ]]; then | |
| install_name_tool -change "$dep" "@loader_path/../$depname" "$target_file" || true | |
| else | |
| install_name_tool -change "$dep" "@loader_path/$depname" "$target_file" || true | |
| fi | |
| done | |
| install_name_tool -add_rpath "@executable_path" "$target_file" 2>/dev/null || true | |
| install_name_tool -add_rpath "@loader_path" "$target_file" 2>/dev/null || true | |
| done | |
| find "raw-binaries/raw-macOS-$arch-static" -type f -name "*.a" -exec strip -S {} + 2>/dev/null || true | |
| done | |
| # 2. Combine with Lipo | |
| mkdir -p dist/{engines,providers,lib/static} | |
| lipo_file() { | |
| local rel_path=$1 | |
| local dest_path=$2 | |
| local f_x86="raw-binaries/raw-macOS-x64-shared/$rel_path" | |
| local f_arm="raw-binaries/raw-macOS-arm64-shared/$rel_path" | |
| if [ ! -f "$f_x86" ]; then | |
| f_x86="raw-binaries/raw-macOS-x64-static/$rel_path" | |
| f_arm="raw-binaries/raw-macOS-arm64-static/$rel_path" | |
| fi | |
| if [ ! -f "$f_x86" ] || [ ! -f "$f_arm" ]; then return 0; fi | |
| lipo -create -output "$dest_path" "$f_x86" "$f_arm" | |
| } | |
| lipo_file "openssl" "dist/openssl" | |
| find raw-binaries/raw-macOS-x64-shared -maxdepth 1 -type f -name "*.dylib" | while read -r f; do | |
| lipo_file "$(basename "$f")" "dist/$(basename "$f")" | |
| done | |
| [ -d "raw-binaries/raw-macOS-x64-shared/engines" ] && find raw-binaries/raw-macOS-x64-shared/engines -type f -name "*.dylib" | while read -r f; do | |
| lipo_file "engines/$(basename "$f")" "dist/engines/$(basename "$f")" | |
| done | |
| [ -d "raw-binaries/raw-macOS-x64-shared/providers" ] && find raw-binaries/raw-macOS-x64-shared/providers -type f -name "*.dylib" | while read -r f; do | |
| lipo_file "providers/$(basename "$f")" "dist/providers/$(basename "$f")" | |
| done | |
| find raw-binaries/raw-macOS-x64-static/lib/static -type f -name "*.a" | while read -r f; do | |
| lipo_file "lib/static/$(basename "$f")" "dist/lib/static/$(basename "$f")" | |
| done | |
| cp raw-binaries/raw-macOS-x64-shared/install_symlinks.sh dist/ 2>/dev/null || true | |
| - name: Finalize Package | |
| shell: bash | |
| run: | | |
| # Copy Common Assets | |
| mkdir -p dist/include dist/doc | |
| cp -R common-assets/include/* dist/include/ 2>/dev/null || true | |
| cp -R common-assets/share/doc/* dist/doc/ 2>/dev/null || true | |
| # Copy License and README from common assets | |
| cp common-assets/LICENSE.txt dist/ 2>/dev/null || true | |
| cp common-assets/README.txt dist/ 2>/dev/null || true | |
| # Create Metadata | |
| if [ "${{ inputs.build_type }}" == "branch" ]; then | |
| echo "branch: ${{ needs.validate-version.outputs.slugified_version }}" > dist/version.txt | |
| else | |
| echo "${{ needs.validate-version.outputs.slugified_version }}" > dist/version.txt | |
| fi | |
| # Create Symlink Script (POSIX only, if not already present) | |
| if [ ! -f dist/install_symlinks.sh ]; then | |
| if [ "${{ matrix.label }}" == "Linux" ] || [ "${{ matrix.label }}" == "macOS" ]; then | |
| echo "#!/bin/sh" > dist/install_symlinks.sh | |
| echo "echo \"Restoring shared library symlinks...\"" >> dist/install_symlinks.sh | |
| cd dist | |
| for lib in libcrypto libssl; do | |
| if [ "${{ matrix.label }}" == "Linux" ]; then | |
| REAL_FILE=$(ls ${lib}.so.* 2>/dev/null | head -n 1) | |
| if [ -n "$REAL_FILE" ]; then | |
| echo "ln -sf $REAL_FILE ${lib}.so" >> install_symlinks.sh | |
| fi | |
| else | |
| REAL_FILE=$(ls ${lib}.*.dylib 2>/dev/null | head -n 1) | |
| if [ -n "$REAL_FILE" ]; then | |
| echo "ln -sf $REAL_FILE ${lib}.dylib" >> install_symlinks.sh | |
| fi | |
| fi | |
| done | |
| chmod +x install_symlinks.sh | |
| cd - > /dev/null | |
| fi | |
| fi | |
| find dist -type d -empty -delete | |
| ARCHIVE_NAME="openssl-${{ needs.validate-version.outputs.artifact_version }}-${{ matrix.label }}-${{ matrix.arch }}.zip" | |
| cd dist | |
| zip -r -y "../$ARCHIVE_NAME" . | |
| cd .. | |
| echo "ARCHIVE_FILE=$ARCHIVE_NAME" >> $GITHUB_ENV | |
| - name: Upload Final Archive | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: openssl-${{ needs.validate-version.outputs.artifact_version }}-${{ matrix.label }}-${{ matrix.arch }} | |
| path: ${{ env.ARCHIVE_FILE }} | |
| archive: false | |
| retention-days: 5 | |
| - name: Upload Build Metadata (Once) | |
| if: matrix.label == 'Linux' && matrix.arch == 'x64' && needs.validate-version.outputs.is_fork == 'false' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-metadata | |
| path: dist/version.txt | |
| retention-days: 5 | |
| # ========================================================================= | |
| # 4. CLEANUP RAW ARTIFACTS | |
| # ========================================================================= | |
| cleanup-artifacts: | |
| name: Cleanup Intermediate Artifacts | |
| needs: package-release | |
| runs-on: ubuntu-latest | |
| if: inputs.keep_raw_artifacts != true | |
| permissions: | |
| actions: write | |
| steps: | |
| - name: Delete Raw and Common Artifacts | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "Fetching artifacts for run ${{ github.run_id }}..." | |
| # Use gh api to list artifacts | |
| ARTIFACTS=$(gh api repos/${{ github.repository }}/actions/artifacts --paginate) | |
| # Filter for IDs of artifacts that start with 'raw-' or are 'openssl-common-assets' | |
| IDS=$(echo "$ARTIFACTS" | jq -r '.artifacts[] | select (.name | startswith("raw-") or . == "openssl-common-assets") | .id') | |
| if [ -z "$IDS" ] || [ "$IDS" == "null" ]; then | |
| echo "No intermediate artifacts found to delete." | |
| exit 0 | |
| fi | |
| for id in $IDS; do | |
| echo "Deleting artifact ID: $id" | |
| gh api -X DELETE repos/${{ github.repository }}/actions/artifacts/$id || echo "Failed to delete artifact ID: $id" ; true # Continue even if deletion fails | |
| done | |
| echo "✅ Cleanup complete." |