name: Build LMS

# Test using act: act -W .github/workflows/00_build.yaml --pull=false

on:
  workflow_dispatch:
    inputs:
      branch:
        type: string
        description: 'The branch from which to build from'
        required: true
        # TODO - make this dynamic, or something like https://dev.to/mrmike/github-action-handling-input-default-value-5f2g?
        default: public/9.0
      build_type:
        type: choice
        description: 'Is this a nightly or a release build?'
        required: true
        default: 'nightly'
        options:
          - nightly
          - release

jobs:
  mac:
    name: Build LMS for Mac
    runs-on: macos-15
    env:
      BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
      P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
      KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
      DEV_CERT_NAME: ${{ secrets.DEV_CERT_NAME }}
      APPLE_ID: ${{ secrets.APPLE_ID }}
      NOTARIZATION_PW: ${{ secrets.NOTARIZATION_PW }}
      TEAM_ID: ${{ secrets.TEAM_ID }}
    steps:
      # we must check out here, as  otherwise the build action is not available
      - name: Check out LMS code
        uses: actions/checkout@v6
        with:
          path: server
          ref: ${{ inputs.branch }}

      - name: Install the Apple certificate and provisioning profile
        run: |
          echo "::group::Install the Apple certificate and provisioning profile"
          # create variables
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

          # import certificate and provisioning profile from secrets
          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH

          # create temporary keychain
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

          # import certificate to keychain
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH

          echo "::endgroup::"

      - name: Launch build process
        uses: ./server/.github/actions/build
        with:
          build-params: macos
          build-type: ${{ inputs.build_type }}
          AWS_KEY_ID: ${{ secrets.R2_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}

  linux:
    name: Build LMS for Linux
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        flavour:
          - [debian, "--x86_64"]
          - [debian, "--arm"]
          - [debian, ""]
          - [rpm, ""]
          - [tarball, "--arm"]
          - [tarball, ""]
          - [tarball, "--encore"]
          - [tarball, "--noCPAN"]
          - [pcp, ""]

    steps:
      # we must check out here, as  otherwise the build action is not available
      - name: Check out LMS code
        uses: actions/checkout@v6
        with:
          path: server
          ref: ${{ inputs.branch }}

      - name: Prepare build environment
        if: ${{ matrix.flavour[0] != 'tarball' && matrix.flavour[0] != 'pcp' }}
        uses: awalsh128/cache-apt-pkgs-action@latest
        with:
          packages: apt-transport-https debhelper devscripts
          version: 1

      - name: Launch build process
        uses: ./server/.github/actions/build
        with:
          build-params: ${{ matrix.flavour[0] }} ${{ matrix.flavour[1] }}
          build-type: ${{ inputs.build_type }}
          AWS_KEY_ID: ${{ secrets.R2_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}

  docker:
    name: Build LMS for Docker
    runs-on: ubuntu-22.04

    steps:
      # we must check out here, as  otherwise the build action is not available
      - name: Check out LMS code
        uses: actions/checkout@v6
        with:
          path: server
          ref: ${{ inputs.branch }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to ghcr.io
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Launch build process
        uses: ./server/.github/actions/build
        with:
          build-params: docker --registry "ghcr.io/${{ github.repository_owner }}"
          build-type: ${{ inputs.build_type }}

  win64:
    name: Build LMS for Windows (64-bit)
    runs-on: windows-2022
    steps:
      # we must check out here, as  otherwise the build action is not available
      - name: Check out LMS code
        uses: actions/checkout@v6
        with:
          path: server
          ref: ${{ inputs.branch }}

      - name: Launch build process
        uses: ./server/.github/actions/build
        with:
          build-params: win64
          build-type: ${{ inputs.build_type }}
          AWS_KEY_ID: ${{ secrets.R2_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
          SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
          SIGNPATH_ORG_ID: ${{ vars.SIGNPATH_ORG_ID }}
          SIGNPATH_PROJECT_SLUG: ${{ vars.SIGNPATH_PROJECT_SLUG }}
          SIGNPATH_SIGNING_POLICY_SLUG: ${{ vars.SIGNPATH_SIGNING_POLICY_SLUG }}
          SIGNPATH_ARTIFACT_CONFIG_SLUG: ${{ vars.SIGNPATH_ARTIFACT_CONFIG_SLUG }}

      - name: Archive signed Windows artifact
        # we only sign for release builds - no need to do this for nightlies
        if: ${{ inputs.build-type == 'release' }}
        # needs to be run here as the above build action can't run upload twice
        uses: actions/upload-artifact@v6
        id: upload-artifact
        with:
          name: win64-signed
          path: publish/

  updateRepoFile:
    name: Trigger repository file update
    if: ${{ success() && inputs.build_type == 'nightly' && github.repository_owner == 'LMS-Community' }}
    runs-on: ubuntu-latest
    timeout-minutes: 2
    needs:
      - mac
      - linux
      - win64
    permissions:
      actions: write
    steps:
      - env:
          GH_TOKEN: ${{ secrets.DEPLOYMENT_KEY }}
        run: gh workflow run update-server-repository.yml -R https://github.com/LMS-Community/lms-server-repository

  tagRelease:
    name: Tag the current release
    if: ${{ success() && inputs.build_type == 'release' && github.repository_owner == 'LMS-Community' }}
    runs-on: ubuntu-latest
    needs:
      - updateRepoFile
    permissions:
      actions: write
      contents: write
    steps:
      # no easy way to avoid another checkout?
      - name: Check out LMS code
        uses: actions/checkout@v4
        with:
          path: server
          ref: ${{ inputs.branch }}
      - name: Tag that thang
        run: |
          cd server
          VERSION=$(grep "our \$VERSION" -m1 slimserver.pl | cut -d"'" -f2)
          git config user.name "LMS Server Repository Updater"
          git config user.email "gitmaster@lms-community.org"
          git tag -a -m -f "$VERSION"
          git push origin refs/tags/$VERSION