name: Release packages

on:
  workflow_dispatch:
    inputs:
      tag:
        description: Release tag, for example v3.2.0
        required: true
        type: string

permissions:
  contents: write

env:
  BUILD_TYPE: Release

jobs:
  linux:
    runs-on: ubuntu-22.04

    steps:
    - uses: actions/checkout@v3
      with:
        ref: ${{ inputs.tag }}

    - name: Build, test, and package
      env:
        TAG: ${{ inputs.tag }}
      run: |
        set -eux
        VERSION="${TAG#v}"
        PACKAGE="GmSSL-${VERSION}-Linux-x86_64"
        PREFIX="${PWD}/${PACKAGE}"
        STATIC_PREFIX="${PWD}/${PACKAGE}-static"

        rm -rf build-shared build-static "${PREFIX}" "${STATIC_PREFIX}" "${PACKAGE}.tar.gz"

        cmake -S . -B build-shared \
          -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
          -DBUILD_SHARED_LIBS=ON \
          -DCMAKE_INSTALL_PREFIX="${PREFIX}"
        cmake --build build-shared --config "${BUILD_TYPE}"
        cmake --install build-shared --prefix "${PREFIX}"
        "${PREFIX}/bin/gmssl" version | grep "GmSSL ${VERSION}"

        cmake -S . -B build-static \
          -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
          -DBUILD_SHARED_LIBS=OFF \
          -DCMAKE_INSTALL_PREFIX="${STATIC_PREFIX}"
        cmake --build build-static --config "${BUILD_TYPE}"
        cmake --install build-static --prefix "${STATIC_PREFIX}"
        cp "${STATIC_PREFIX}/bin/gmssl" "${PREFIX}/bin/gmssl"
        cp "${STATIC_PREFIX}/lib/libgmssl.a" "${PREFIX}/lib/libgmssl.a"
        if ldd "${PREFIX}/bin/gmssl" | grep -q libgmssl; then
          echo "gmssl must not depend on libgmssl.so" >&2
          exit 1
        fi

        cat > smoke.c <<'EOF'
        #include <stdio.h>
        #include <gmssl/version.h>

        int main(void)
        {
                puts(gmssl_version_str());
                return 0;
        }
        EOF
        cc smoke.c -I"${PREFIX}/include" "${PREFIX}/lib/libgmssl.a" -o smoke-static
        ./smoke-static | grep "GmSSL ${VERSION}"

        tar czf "${PACKAGE}.tar.gz" "${PACKAGE}"

    - name: Upload Linux package
      env:
        GH_TOKEN: ${{ github.token }}
        TAG: ${{ inputs.tag }}
      run: |
        VERSION="${TAG#v}"
        gh release upload "${TAG}" "GmSSL-${VERSION}-Linux-x86_64.tar.gz" --clobber

  macos:
    strategy:
      matrix:
        include:
        - arch: arm64
          runner: macos-15
        - arch: x86_64
          runner: macos-15-intel
    runs-on: ${{ matrix.runner }}

    steps:
    - uses: actions/checkout@v3
      with:
        ref: ${{ inputs.tag }}

    - name: Build, test, and package
      env:
        TAG: ${{ inputs.tag }}
        ARCH: ${{ matrix.arch }}
      run: |
        set -eux
        VERSION="${TAG#v}"
        PACKAGE="GmSSL-${VERSION}-macOS-${ARCH}"
        PREFIX="${PWD}/${PACKAGE}"
        STATIC_PREFIX="${PWD}/${PACKAGE}-static"

        rm -rf build-shared build-static "${PREFIX}" "${STATIC_PREFIX}" "${PACKAGE}.tar.gz"

        cmake -S . -B build-shared \
          -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
          -DCMAKE_OSX_ARCHITECTURES="${ARCH}" \
          -DBUILD_SHARED_LIBS=ON \
          -DCMAKE_INSTALL_PREFIX="${PREFIX}"
        cmake --build build-shared --config "${BUILD_TYPE}"
        cmake --install build-shared --prefix "${PREFIX}"
        "${PREFIX}/bin/gmssl" version | grep "GmSSL ${VERSION}"

        cmake -S . -B build-static \
          -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
          -DCMAKE_OSX_ARCHITECTURES="${ARCH}" \
          -DBUILD_SHARED_LIBS=OFF \
          -DCMAKE_INSTALL_PREFIX="${STATIC_PREFIX}"
        cmake --build build-static --config "${BUILD_TYPE}"
        cmake --install build-static --prefix "${STATIC_PREFIX}"
        cp "${STATIC_PREFIX}/bin/gmssl" "${PREFIX}/bin/gmssl"
        cp "${STATIC_PREFIX}/lib/libgmssl.a" "${PREFIX}/lib/libgmssl.a"

        file "${PREFIX}/bin/gmssl" | grep "${ARCH}"
        if otool -L "${PREFIX}/bin/gmssl" | grep -q libgmssl; then
          echo "gmssl must not depend on libgmssl.dylib" >&2
          exit 1
        fi
        "${PREFIX}/bin/gmssl" version | grep "GmSSL ${VERSION}"

        cat > smoke.c <<'EOF'
        #include <stdio.h>
        #include <gmssl/version.h>

        int main(void)
        {
                puts(gmssl_version_str());
                return 0;
        }
        EOF
        cc smoke.c -I"${PREFIX}/include" "${PREFIX}/lib/libgmssl.a" -o smoke-static
        ./smoke-static | grep "GmSSL ${VERSION}"

        tar czf "${PACKAGE}.tar.gz" "${PACKAGE}"

    - name: Upload macOS package
      env:
        GH_TOKEN: ${{ github.token }}
        TAG: ${{ inputs.tag }}
        ARCH: ${{ matrix.arch }}
      run: |
        VERSION="${TAG#v}"
        gh release upload "${TAG}" "GmSSL-${VERSION}-macOS-${ARCH}.tar.gz" --clobber

  windows:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v3
      with:
        ref: ${{ inputs.tag }}

    - name: Configure Visual Studio environment
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: x64

    - name: Build, test, and package
      shell: pwsh
      env:
        TAG: ${{ inputs.tag }}
      run: |
        $ErrorActionPreference = "Stop"
        $Version = $env:TAG.TrimStart("v")
        $Package = "GmSSL-$Version-win64"
        $Prefix = Join-Path $PWD $Package
        $StaticPrefix = Join-Path $PWD "$Package-static"

        Remove-Item -Recurse -Force build-shared, build-static, $Prefix, $StaticPrefix, "$Package.zip" -ErrorAction SilentlyContinue

        cmake -S . -B build-shared -G "NMake Makefiles" `
          -DCMAKE_BUILD_TYPE="$env:BUILD_TYPE" `
          -DBUILD_SHARED_LIBS=ON `
          -DCMAKE_INSTALL_PREFIX="$Prefix"
        cmake --build build-shared --config "$env:BUILD_TYPE"
        cmake --install build-shared --prefix "$Prefix"

        $SharedImportLib = Join-Path $Prefix "lib\gmssl.lib"
        if (Test-Path $SharedImportLib) {
          Copy-Item $SharedImportLib (Join-Path $Prefix "lib\gmssl_shared.lib") -Force
        }

        cmake -S . -B build-static -G "NMake Makefiles" `
          -DCMAKE_BUILD_TYPE="$env:BUILD_TYPE" `
          -DBUILD_SHARED_LIBS=OFF `
          -DCMAKE_INSTALL_PREFIX="$StaticPrefix"
        cmake --build build-static --config "$env:BUILD_TYPE"
        cmake --install build-static --prefix "$StaticPrefix"

        Copy-Item (Join-Path $StaticPrefix "bin\gmssl.exe") (Join-Path $Prefix "bin\gmssl.exe") -Force
        $StaticLib = Join-Path $StaticPrefix "lib\gmssl.lib"
        if (Test-Path $StaticLib) {
          Copy-Item $StaticLib (Join-Path $Prefix "lib\gmssl_static.lib") -Force
        }

        & (Join-Path $Prefix "bin\gmssl.exe") version | Select-String "GmSSL $Version"
        $Dependents = & dumpbin /dependents (Join-Path $Prefix "bin\gmssl.exe")
        $Dependents | Out-String | Write-Host
        if ($Dependents -match "gmssl.dll") {
          throw "gmssl.exe must not depend on gmssl.dll"
        }
        @"
        #include <stdio.h>
        #include <gmssl/version.h>

        int main(void)
        {
                puts(gmssl_version_str());
                return 0;
        }
        "@ | Set-Content -Encoding ASCII smoke.c
        cl /nologo smoke.c /I "$Prefix\include" "$Prefix\lib\gmssl_static.lib" /Fe:smoke-static.exe
        .\smoke-static.exe | Select-String "GmSSL $Version"

        Compress-Archive -Path $Package -DestinationPath "$Package.zip" -Force

    - name: Upload Windows package
      shell: pwsh
      env:
        GH_TOKEN: ${{ github.token }}
        TAG: ${{ inputs.tag }}
      run: |
        $Version = $env:TAG.TrimStart("v")
        gh release upload $env:TAG "GmSSL-$Version-win64.zip" --clobber
