From 6c601fd5efc5ca9d057a649c59f724a83378abc3 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 15:00:07 -0700 Subject: [PATCH 01/10] Implement support for building from forks with release gatekeeping. --- .github/workflows/build-openssl.yml | 47 +++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index 2d59f70..f106d5e 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -13,7 +13,7 @@ on: - branch default: release version: - description: 'OpenSSL Version or Branch (e.g., 3.4.0 or master)' + description: 'Version or Fork (e.g. 3.4.0, master, or user/repo/branch)' required: true type: string ignore_eol: @@ -53,8 +53,10 @@ jobs: runs-on: ubuntu-latest outputs: version: ${{ steps.check.outputs.version }} + target_repo: ${{ steps.check.outputs.target_repo }} ref: ${{ steps.check.outputs.ref }} artifact_version: ${{ steps.check.outputs.artifact_version }} + is_fork: ${{ steps.check.outputs.is_fork }} steps: - name: Check EOL or Branch Existence id: check @@ -63,6 +65,9 @@ jobs: 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") @@ -80,20 +85,38 @@ jobs: echo "⚠️ Ignore EOL is checked. Proceeding anyway." fi fi - echo "ref=openssl-$VERSION" >> $GITHUB_OUTPUT - echo "artifact_version=$VERSION" >> $GITHUB_OUTPUT + TARGET_REF="openssl-$VERSION" + ARTIFACT_VERSION="$VERSION" else # Branch Mode - echo "🔍 Verifying branch '$VERSION' in upstream repository..." - if ! git ls-remote --heads https://github.com/openssl/openssl.git "$VERSION" | grep -q "$VERSION"; then - echo "❌ Branch '$VERSION' does not exist in openssl/openssl repository." + 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" + USER_PART=$(echo "$VERSION" | cut -d'/' -f1) + ARTIFACT_PART="${USER_PART}_${TARGET_REF}" + else + TARGET_REF="$VERSION" + ARTIFACT_PART="$VERSION" + fi + + echo "🔍 Verifying branch/ref '$TARGET_REF' in repository '$TARGET_REPO'..." + if ! git ls-remote https://github.com/$TARGET_REPO.git "$TARGET_REF" | grep -q "$TARGET_REF"; then + echo "❌ Reference '$TARGET_REF' does not exist in $TARGET_REPO." exit 1 fi + TIMESTAMP=$(date -u +%Y%m%dT%H%M%SZ) - echo "ref=$VERSION" >> $GITHUB_OUTPUT - echo "artifact_version=${VERSION}_${TIMESTAMP}" >> $GITHUB_OUTPUT + # Slugify and truncate ARTIFACT_PART + SAFE_PART=$(echo "$ARTIFACT_PART" | sed 's/\//_/g' | cut -c 1-100) + ARTIFACT_VERSION="${SAFE_PART}_${TIMESTAMP}" fi + echo "target_repo=$TARGET_REPO" >> $GITHUB_OUTPUT + echo "is_fork=$IS_FORK" >> $GITHUB_OUTPUT + echo "ref=$TARGET_REF" >> $GITHUB_OUTPUT + echo "artifact_version=$ARTIFACT_VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT # ========================================================================= @@ -106,7 +129,7 @@ jobs: steps: - uses: actions/checkout@v6 with: - repository: openssl/openssl + repository: ${{ needs.validate-version.outputs.target_repo }} ref: ${{ needs.validate-version.outputs.ref }} - name: Build Common Assets @@ -202,7 +225,7 @@ jobs: steps: - uses: actions/checkout@v6 with: - repository: openssl/openssl + repository: ${{ needs.validate-version.outputs.target_repo }} ref: ${{ needs.validate-version.outputs.ref }} - name: Compile Windows (Standard) @@ -590,7 +613,7 @@ jobs: retention-days: 5 - name: Upload Build Metadata (Once) - if: matrix.label == 'Linux' && matrix.arch == 'x64' + if: matrix.label == 'Linux' && matrix.arch == 'x64' && needs.validate-version.outputs.is_fork == 'false' uses: actions/upload-artifact@v7 with: name: build-metadata @@ -615,7 +638,7 @@ jobs: echo "Fetching artifacts for run ${{ github.run_id }}..." # Use gh api to list artifacts - ARTIFACTS=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts --paginate) + 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') From 710b23c532c46a49585254923d20f3943e89f987 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 15:01:09 -0700 Subject: [PATCH 02/10] Support commit SHAs in fork builds. --- .github/workflows/build-openssl.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index f106d5e..f846cd2 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -102,9 +102,12 @@ jobs: fi echo "🔍 Verifying branch/ref '$TARGET_REF' in repository '$TARGET_REPO'..." - if ! git ls-remote https://github.com/$TARGET_REPO.git "$TARGET_REF" | grep -q "$TARGET_REF"; then - echo "❌ Reference '$TARGET_REF' does not exist in $TARGET_REPO." - exit 1 + # Skip ls-remote check for commit SHAs (40 hex chars) + if [[ ! "$TARGET_REF" =~ ^[0-9a-f]{40}$ ]]; then + if ! git ls-remote https://github.com/$TARGET_REPO.git "$TARGET_REF" | grep -q "$TARGET_REF"; then + echo "❌ Reference '$TARGET_REF' does not exist in $TARGET_REPO." + exit 1 + fi fi TIMESTAMP=$(date -u +%Y%m%dT%H%M%SZ) From 96f3178f86a4274154ba2cad0783043d7b036120 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 15:41:33 -0700 Subject: [PATCH 03/10] Fix job dependency breakage by using a static name for the validation job. --- .github/workflows/build-openssl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index f846cd2..a7ad97f 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -49,7 +49,7 @@ jobs: # 0. VALIDATE VERSION & EOL # ========================================================================= validate-version: - name: Validate ${{ inputs.build_type == 'release' && 'Version' || 'Branch' }} + name: Validate Inputs runs-on: ubuntu-latest outputs: version: ${{ steps.check.outputs.version }} From e560d8cc0f38064359835b1fb906494aa8ad0089 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 20:35:48 -0700 Subject: [PATCH 04/10] Implement human-readable fork naming and deterministic SHA-pinned builds. --- .github/workflows/build-openssl.yml | 49 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index a7ad97f..b7d3a41 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -51,15 +51,21 @@ jobs: 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 }}" @@ -86,7 +92,16 @@ jobs: 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 @@ -94,32 +109,40 @@ jobs: TARGET_REPO=$(echo "$VERSION" | cut -d'/' -f1,2) TARGET_REF=$(echo "$VERSION" | cut -d'/' -f3-) IS_FORK="true" - USER_PART=$(echo "$VERSION" | cut -d'/' -f1) - ARTIFACT_PART="${USER_PART}_${TARGET_REF}" else TARGET_REF="$VERSION" - ARTIFACT_PART="$VERSION" fi - echo "🔍 Verifying branch/ref '$TARGET_REF' in repository '$TARGET_REPO'..." - # Skip ls-remote check for commit SHAs (40 hex chars) - if [[ ! "$TARGET_REF" =~ ^[0-9a-f]{40}$ ]]; then - if ! git ls-remote https://github.com/$TARGET_REPO.git "$TARGET_REF" | grep -q "$TARGET_REF"; then + 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 and truncate ARTIFACT_PART - SAFE_PART=$(echo "$ARTIFACT_PART" | sed 's/\//_/g' | cut -c 1-100) + # 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 + # Dynamically update the Run Name for better visibility in UI + gh run edit ${{ github.run_id }} --name "Build OpenSSL $SLUGIFIED_VERSION via ${{ github.event_name }}" || true + 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 # ========================================================================= @@ -133,7 +156,7 @@ jobs: - uses: actions/checkout@v6 with: repository: ${{ needs.validate-version.outputs.target_repo }} - ref: ${{ needs.validate-version.outputs.ref }} + ref: ${{ needs.validate-version.outputs.sha }} - name: Build Common Assets run: | @@ -229,7 +252,7 @@ jobs: - uses: actions/checkout@v6 with: repository: ${{ needs.validate-version.outputs.target_repo }} - ref: ${{ needs.validate-version.outputs.ref }} + ref: ${{ needs.validate-version.outputs.sha }} - name: Compile Windows (Standard) if: matrix.platform.label == 'Windows' && matrix.platform.arch != 'arm64ec' @@ -582,9 +605,9 @@ jobs: # Create Metadata if [ "${{ inputs.build_type }}" == "branch" ]; then - echo "branch: ${{ needs.validate-version.outputs.version }}" > dist/version.txt + echo "branch: ${{ needs.validate-version.outputs.slugified_version }}" > dist/version.txt else - echo "${{ needs.validate-version.outputs.version }}" > dist/version.txt + echo "${{ needs.validate-version.outputs.slugified_version }}" > dist/version.txt fi # Create Symlink Script (POSIX only, if not already present) From e1f5e92fdaccf0f0b4c5d9f6786b387f4eda9aab Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 21:11:58 -0700 Subject: [PATCH 05/10] Input descripttions update --- .github/workflows/build-openssl.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index b7d3a41..01fa458 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -5,15 +5,15 @@ on: workflow_dispatch: inputs: build_type: - description: 'Build Type' + description: 'Build Source' required: true type: choice options: - release - - branch + - branch or fork default: release version: - description: 'Version or Fork (e.g. 3.4.0, master, or user/repo/branch)' + 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: From 975876e0aa137cd453760eaac65c03cf2423bd10 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Sun, 15 Mar 2026 21:15:29 -0700 Subject: [PATCH 06/10] Refine build input descriptions and update Maintainer Guide to reflect fork support and deterministic builds. --- .github/workflows/build-openssl.yml | 4 +-- doc/MAINTAINING.md | 47 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index 01fa458..6f774fe 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -5,12 +5,12 @@ on: workflow_dispatch: inputs: build_type: - description: 'Build Source' + description: 'Build Source: OpenSSL Release or OpenSSL Branch/OpenSSL fork' required: true type: choice options: - release - - branch or fork + - 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)' diff --git a/doc/MAINTAINING.md b/doc/MAINTAINING.md index 8687fd2..24c4418 100644 --- a/doc/MAINTAINING.md +++ b/doc/MAINTAINING.md @@ -13,23 +13,22 @@ The pipeline consists of three primary workflows: * Explicitly passes `build_type="release"` to ensure correct mode selection. 2. **Build (`build-openssl.yml`):** - * **Validate Mode & Version:** Handles two build modes: - * `release`: Uses official tags (e.g., `openssl-3.4.0`) and performs EOL checks. - * `branch`: Clones a specific git branch (e.g., `master`, `openssl-3.0`) and verifies its existence. + * **Validate Mode & Version:** Handles three build scenarios: + * `release`: Uses official tags (e.g., `3.4.0`) and performs EOL checks. + * `branch`: Clones an official branch (e.g., `master`, `openssl-3.1`). + * `fork`: Clones a public fork using the `user/repo/branch` format. + * **Deterministic Builds:** The validator resolves all inputs to a specific **Commit SHA** at the start of the run. All subsequent jobs (Compile, Package) use this SHA to ensure "point-in-time" consistency. + * **Human-Readable UI:** The workflow dynamically updates the GitHub Run Name to a slugified `user_repo_branch` scheme (e.g., `Build OpenSSL slontis_openssl_fix-logic`) for better visibility. * **Build Common Assets:** Compiles architecture-independent headers and HTML docs once. - * Generates a centralized `README.txt`. - * Extracts `LICENSE.txt` from the source root. - * Removes unnecessary large directories to keep the "common assets" artifact lean. - * **Compile Binaries (Fan-Out):** A highly parallel matrix that splits builds by OS, Architecture, AND Linkage (`shared` vs `static`). Uses parallelized `make -j$(nproc)` for speed. - * **Package Release (Fan-In):** Downloads assets and raw binaries. - * *Adaptive Merging:* Handles inconsistent `actions/download-artifact` behavior by detecting both nested and flattened artifact structures. - * *macOS:* Combines x64 and arm64 into Universal binaries using `lipo` and `install_name_tool`. - * *Naming:* Releases use standard version naming; Branch builds use `_` (e.g., `master_20260314T150000Z`). - * *Metadata:* Generates `version.txt`. If in `branch` mode, prepends `branch: ` to the content. - * **Cleanup:** Deletes intermediate artifacts via GitHub API unless `keep_raw_artifacts` is true. + * **Compile Binaries (Fan-Out):** A highly parallel matrix that splits builds by OS, Architecture, AND Linkage. + * **Package Release (Fan-In):** + * *Slugified Naming:* Filenames and internal metadata use a standardized `user_repo_branch` scheme where all `/` are replaced by `_`. + * *Release Gatekeeping:* If a build is detected as a **Fork**, the workflow intentionally withholds the `build-metadata` artifact. This acts as a "hard stop" that prevents the Publish workflow from creating an official release from untrusted code. + * **Cleanup:** Deletes intermediate artifacts unless `keep_raw_artifacts` is true. 3. **Publish (`publish-release.yml`):** - * Triggered automatically when a Build completes. + * Triggered automatically when a Build completes (on `main` branch). + * Requires the `build-metadata` artifact to function. * Creates a Draft release and opens a GitHub Issue for maintainer review. ## 🛠️ Manual Operations @@ -37,16 +36,21 @@ The pipeline consists of three primary workflows: ### How to build manually 1. Go to **Actions** tab -> **Build OpenSSL 3.x**. 2. Click **Run workflow**. -3. **Build Type:** Select `release` for official tags or `branch` for moving git branches. -4. **OpenSSL Version or Branch:** Enter the tag (e.g., `3.4.0`) or branch name (e.g., `openssl-3.6`). -5. *(Optional)* Check **Ignore EOL Check** if you need to build an unsupported release. -6. *(Optional)* Check **Keep raw build artifacts** for debugging. +3. **Build Source:** + * Select `release` for official OpenSSL releases (tags). + * Select `branch` for official OpenSSL branches or external OpenSSL forks. +4. **OpenSSL Release Version, OpenSSL Branch Name or OpenSSL Fork Repo:** + * Official Release: `3.4.0` + * Official Branch: `master` + * OpenSSL Fork: `user/repo/branch` (e.g., `slontis/openssl/fix-arm64ec`) +5. *(Optional)* Check **Ignore EOL Check** for legacy builds. +6. *(Optional)* Check **Keep raw build artifacts** for debugging compilation issues. ### How to publish a release manually If an automatic publish fails: 1. Go to **Actions** tab -> **Publish Release**. 2. Click **Run workflow**. -3. Provide the **Build Workflow Run ID** (found in the URL of the successful build run). +3. Provide the **Build Workflow Run ID**. 4. Toggle **Create as Draft** as needed. ### Reviewing and Publishing Drafts @@ -55,8 +59,3 @@ If an automatic publish fails: 3. Verify the artifacts and release notes. 4. Click **Edit**, uncheck "Set as a draft", and click **Publish release**. 5. Close the notification issue. - -### Secrets Configuration -* **Secret Name:** `RBPW_PAT` -* **Required Scopes:** `repo`, `actions:write`. -* **Note:** Required for workflow chaining (`check-upstream` -> `build-openssl`). Standard operations use the default `GITHUB_TOKEN`. From 9079b2d49abc5e2f15333e6c98126a8b3c0078dd Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Tue, 17 Mar 2026 18:32:04 -0700 Subject: [PATCH 07/10] Support OpenSSL 4.0 by making shared library handling version-agnostic and dynamically generating symlinks. --- .github/workflows/build-openssl.yml | 68 +++++++++++++++++++++-------- README.md | 8 ++-- doc/MAINTAINING.md | 2 +- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index 6f774fe..c0bdb48 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -1,4 +1,4 @@ -name: Build OpenSSL 3.x +name: Build OpenSSL run-name: Build OpenSSL ${{ inputs.version }} via ${{ github.event_name }} on: @@ -198,7 +198,7 @@ jobs: ----------------------------------------------- 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.3). + 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 $ sh ./install_symlinks.sh @@ -389,14 +389,16 @@ jobs: 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 - find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "*.so.3" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true - find "$PREFIX/lib" "$PREFIX/lib64" -maxdepth 1 -type f -name "*.3.dylib" -exec cp {} raw_artifact/dist/ \; 2>/dev/null || true + # 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-3/*.so" -exec cp {} raw_artifact/dist/engines/ \; 2>/dev/null || true - find "$PREFIX" -path "*/engines-3/*.dylib" -exec cp {} raw_artifact/dist/engines/ \; 2>/dev/null || true + 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 @@ -407,12 +409,26 @@ jobs: fi # Symlinks script (Linux/macOS) - if [ "$LABEL" == "Linux" ]; then - echo -e "#!/bin/sh\necho \"Restoring shared library symlinks...\"\nln -sf libcrypto.so.3 libcrypto.so\nln -sf libssl.so.3 libssl.so" > raw_artifact/dist/install_symlinks.sh - chmod +x raw_artifact/dist/install_symlinks.sh - elif [ "$LABEL" == "macOS" ]; then - echo -e "#!/bin/sh\necho \"Restoring shared library symlinks...\"\nln -sf libcrypto.3.dylib libcrypto.dylib\nln -sf libssl.3.dylib libssl.dylib" > raw_artifact/dist/install_symlinks.sh - chmod +x raw_artifact/dist/install_symlinks.sh + 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 @@ -612,12 +628,26 @@ jobs: # Create Symlink Script (POSIX only, if not already present) if [ ! -f dist/install_symlinks.sh ]; then - if [ "${{ matrix.label }}" == "Linux" ]; then - echo -e "#!/bin/sh\necho \"Restoring shared library symlinks...\"\nln -sf libcrypto.so.3 libcrypto.so\nln -sf libssl.so.3 libssl.so" > dist/install_symlinks.sh - chmod +x dist/install_symlinks.sh - elif [ "${{ matrix.label }}" == "macOS" ]; then - echo -e "#!/bin/sh\necho \"Restoring shared library symlinks...\"\nln -sf libcrypto.3.dylib libcrypto.dylib\nln -sf libssl.3.dylib libssl.dylib" > dist/install_symlinks.sh - chmod +x dist/install_symlinks.sh + 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 diff --git a/README.md b/README.md index d6e94b7..a299c16 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,15 @@ When redistributing OpenSSL alongside your application, you only need to deploy #### 🔴 REQUIRED (Must be deployed) These files are strictly required for your application to run and to comply with licensing. -* **`libcrypto`** shared library (e.g., `libcrypto-3-x64.dll`, `libcrypto.so.3`, `libcrypto.3.dylib`) -* **`libssl`** shared library (e.g., `libssl-3-x64.dll`, `libssl.so.3`, `libssl.3.dylib`) +* **`libcrypto`** shared library (e.g., `libcrypto-X-x64.dll`, `libcrypto.so.X`, `libcrypto.X.dylib`) +* **`libssl`** shared library (e.g., `libssl-X-x64.dll`, `libssl.so.X`, `libssl.X.dylib`) * **`LICENSE.txt`** (Required by the Apache License 2.0) #### 🟡 OPTIONAL (Deploy only if needed) Include these only if your application explicitly relies on them. * **`openssl` / `openssl.exe`** (The standalone command-line utility) * **`engines/`** (Legacy hardware/engine support modules) -* **`providers/`** (OpenSSL 3.x provider modules, such as `legacy.dll` / `legacy.so`) +* **`providers/`** (OpenSSL provider modules, such as `legacy.dll` / `legacy.so`) #### ⛔ DO NOT DEPLOY (Development only) These files are for compiling/linking your software and should **not** be shipped to end-users. @@ -54,7 +54,7 @@ These files are for compiling/linking your software and should **not** be shippe #### 🐧 POSIX Specifics (Linux / macOS / Unix) Windows file systems often fail to extract Unix symbolic links. To ensure cross-platform compatibility, our archives contain **only the physical shared library files** (no symlinks). -If your package includes the `install_symlinks.sh` script, you **MUST** run it from the root of the extracted directory on your target POSIX system to recreate the required library symlinks (e.g., `libcrypto.so` -> `libcrypto.so.3`). +If your package includes the `install_symlinks.sh` script, you **MUST** run it from the root of the extracted directory on your target POSIX system to recreate the required library symlinks (e.g., `libcrypto.so` -> `libcrypto.so.X`). ```bash $ cd diff --git a/doc/MAINTAINING.md b/doc/MAINTAINING.md index 24c4418..b2371d2 100644 --- a/doc/MAINTAINING.md +++ b/doc/MAINTAINING.md @@ -34,7 +34,7 @@ The pipeline consists of three primary workflows: ## 🛠️ Manual Operations ### How to build manually -1. Go to **Actions** tab -> **Build OpenSSL 3.x**. +1. Go to **Actions** tab -> **Build OpenSSL**. 2. Click **Run workflow**. 3. **Build Source:** * Select `release` for official OpenSSL releases (tags). From 19756b82cb7021b0ec8f6d20a7832ea5ca30149c Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Tue, 17 Mar 2026 18:34:05 -0700 Subject: [PATCH 08/10] Update publish-release trigger to match the renamed build workflow. --- .github/workflows/publish-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index dde9071..c0d63e6 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -14,7 +14,7 @@ on: # Automatic Trigger (Chained) workflow_run: - workflows: ["Build OpenSSL 3.x"] + workflows: ["Build OpenSSL"] types: - completed branches: From 418e2a7ad5643e1d0938f2b0ba129b343fc42a29 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Tue, 17 Mar 2026 21:14:03 -0700 Subject: [PATCH 09/10] Remove unsupported dynamic run-name editing to fix build failures. --- .github/workflows/build-openssl.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index c0bdb48..2c27bb2 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -134,9 +134,7 @@ jobs: ARTIFACT_VERSION="${SAFE_PART}_${TIMESTAMP}" fi - # Dynamically update the Run Name for better visibility in UI - gh run edit ${{ github.run_id }} --name "Build OpenSSL $SLUGIFIED_VERSION via ${{ github.event_name }}" || true - + # Output resolved information echo "target_repo=$TARGET_REPO" >> $GITHUB_OUTPUT echo "is_fork=$IS_FORK" >> $GITHUB_OUTPUT echo "ref=$TARGET_REF" >> $GITHUB_OUTPUT From e551ad172553836844a700c1c88c752b87fcd7f8 Mon Sep 17 00:00:00 2001 From: "Alexander Tregubov (aka (@)AT)" Date: Tue, 17 Mar 2026 21:47:34 -0700 Subject: [PATCH 10/10] Finalize version-agnostic engine and provider detection for OpenSSL 4.0 support. --- .github/workflows/build-openssl.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-openssl.yml b/.github/workflows/build-openssl.yml index 2c27bb2..381d156 100644 --- a/.github/workflows/build-openssl.yml +++ b/.github/workflows/build-openssl.yml @@ -307,8 +307,8 @@ jobs: mkdir raw_artifact\dist\lib\import copy "%PREFIX%\bin\openssl.exe" raw_artifact\dist\ copy "%PREFIX%\bin\*.dll" raw_artifact\dist\ - copy "%PREFIX%\lib\engines-3\*.dll" raw_artifact\dist\engines\ - copy "%PREFIX%\lib\ossl-modules\*.dll" raw_artifact\dist\providers\ + 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 @@ -397,8 +397,8 @@ jobs: # 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 + 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