name: Windows CI / Build Portable Package

on:
  workflow_call:
    inputs:
      release:
        required: true
        type: boolean
      llvm_version:
        required: true
        type: string
      llvm_targets:
        required: true
        type: string
      llvm_ldflags:
        required: true
        type: string

permissions: {}

jobs:
  build:
    runs-on: windows-2025
    steps:
      - name: Disable CRLF line ending substitution
        run: |
          git config --global core.autocrlf false

      - name: Enable Developer Command Prompt
        uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0

      - name: Install Crystal
        uses: crystal-lang/install-crystal@v1
        id: install-crystal
        with:
          crystal: "1.19.1"

      - name: Download Crystal source
        uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Restore libraries
        uses: actions/cache/restore@v5
        with:
          path: |
            libs/pcre2-8.lib
            libs/iconv.lib
            libs/gc.lib
            libs/ffi.lib
            libs/z.lib
            libs/mpir.lib
            libs/yaml.lib
            libs/xml2.lib
            libs/libxml_VERSION
          key: win-libs-${{ hashFiles('.github/workflows/win.yml', 'etc/win-ci/*.ps1') }}-msvc
          fail-on-cache-miss: true
      - name: Restore OpenSSL
        uses: actions/cache/restore@v5
        with:
          path: |
            libs/crypto.lib
            libs/ssl.lib
            libs/openssl_VERSION
          key: win-openssl-libs-3.4.1-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
          fail-on-cache-miss: true
      - name: Restore DLLs
        uses: actions/cache/restore@v5
        with:
          path: |
            libs/pcre2-8-dynamic.lib
            libs/iconv-dynamic.lib
            libs/gc-dynamic.lib
            libs/ffi-dynamic.lib
            libs/z-dynamic.lib
            libs/mpir-dynamic.lib
            libs/yaml-dynamic.lib
            libs/xml2-dynamic.lib
            dlls/pcre2-8.dll
            dlls/iconv-2.dll
            dlls/gc.dll
            dlls/libffi.dll
            dlls/zlib1.dll
            dlls/mpir.dll
            dlls/yaml.dll
            dlls/libxml2.dll
          key: win-dlls-${{ hashFiles('.github/workflows/win.yml', 'etc/win-ci/*.ps1') }}-msvc
          fail-on-cache-miss: true
      - name: Restore OpenSSL DLLs
        uses: actions/cache/restore@v5
        with:
          path: |
            libs/crypto-dynamic.lib
            libs/ssl-dynamic.lib
            dlls/libcrypto-3-x64.dll
            dlls/libssl-3-x64.dll
          key: win-openssl-dlls-3.4.1-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
          fail-on-cache-miss: true
      - name: Restore LLVM DLLs
        uses: actions/cache/restore@v5
        with:
          path: |
            libs/llvm_VERSION
            libs/llvm-dynamic.lib
            dlls/LLVM-C.dll
          key: llvm-dlls-${{ inputs.llvm_version }}-${{ hashFiles('etc/win-ci/build-llvm.ps1') }}-msvc
          fail-on-cache-miss: true

      - name: Set up environment
        run: |
          Add-Content $env:GITHUB_ENV "CRYSTAL_LIBRARY_PATH=$(pwd)\libs"
          Add-Content $env:GITHUB_ENV "LLVM_VERSION=$env:INPUTS_LLVM_VERSION"
          Add-Content $env:GITHUB_ENV "LLVM_TARGETS=$env:INPUTS_LLVM_TARGETS"
          Add-Content $env:GITHUB_ENV "LLVM_LDFLAGS=$env:INPUTS_LLVM_LDFLAGS"
        env:
          INPUTS_LLVM_VERSION: ${{ inputs.llvm_version }}
          INPUTS_LLVM_TARGETS: ${{ inputs.llvm_targets }}
          INPUTS_LLVM_LDFLAGS: ${{ inputs.llvm_ldflags }}

      - name: Build LLVM extensions
        run: make -f Makefile.win deps

      - name: Build Crystal
        run: |
          bin/crystal.bat env
          make -f Makefile.win -B ${{ inputs.release && 'release=1' || '' }} interpreter=1

      - name: Download shards release
        uses: actions/checkout@v6
        with:
          repository: crystal-lang/shards
          ref: v0.20.0
          path: shards
          persist-credentials: false

      - name: Build shards release
        working-directory: ./shards
        run: make -f Makefile.win ${{ inputs.release && 'release=1' || '' }}

      - name: Gather Crystal binaries
        run: |
          make -f Makefile.win install prefix=crystal
          mkdir crystal/lib
          cp shards/bin/shards.exe crystal/
          cp shards/bin/shards.pdb crystal/
          cp libs/* crystal/lib/
          cp dlls/* crystal/
          cp README.md crystal/

      - name: Upload Crystal binaries
        uses: actions/upload-artifact@v7
        with:
          name: crystal
          path: crystal
