#
# Copyright (C) 2022-2024 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

name: pr-check

on:
  pull_request:
    types: [labeled, synchronize, opened, ready_for_review, reopened]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

jobs:
  windows:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: Windows
    runs-on: windows-2022
    timeout-minutes: 60
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run Build
        timeout-minutes: 20
        run: pnpm compile:pull-request

      - name: List Build
        run: ls ./dist/

      - uses: actions/upload-artifact@v4
        with:
          name: windows-installer-x64
          path: ./dist/podman-desktop*-setup-x64.exe

      - uses: actions/upload-artifact@v4
        with:
          name: windows-installer-arm64
          path: ./dist/podman-desktop*-setup-arm64.exe

      - uses: actions/upload-artifact@v4
        with:
          name: windows-exe-x64
          path: ./dist/podman-desktop*-next-x64.exe

      - uses: actions/upload-artifact@v4
        with:
          name: windows-exe-arm64
          path: ./dist/podman-desktop*-next-arm64.exe

  linux:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: Linux
    runs-on: ubuntu-24.04
    timeout-minutes: 40
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Install flatpak
        run: |
          sudo apt-get update
          sudo apt-get install flatpak -y
          sudo apt-get install flatpak-builder -y
          sudo apt-get install elfutils -y
          flatpak remote-add --if-not-exists flathub --user https://flathub.org/repo/flathub.flatpakrepo
          flatpak install flathub --no-static-deltas --user -y org.freedesktop.Platform//23.08 org.freedesktop.Sdk//23.08

      - name: Run Build
        timeout-minutes: 20
        run: pnpm compile:pull-request

      - name: List Build
        run: ls -la ./dist/

      - uses: actions/upload-artifact@v4
        with:
          name: linux
          path: ./dist/podman-desktop-*.tar.gz

      - uses: actions/upload-artifact@v4
        with:
          name: flatpak
          path: ./dist/podman-desktop-*.flatpak

  darwin:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: macOS
    runs-on: macos-14
    timeout-minutes: 40
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run Build
        timeout-minutes: 40
        run: pnpm compile:pull-request

      - name: List Build
        run: ls -la ./dist/

      - uses: actions/upload-artifact@v4
        with:
          name: macos-x64-dmg
          path: ./dist/podman-desktop-*x64.dmg
      - uses: actions/upload-artifact@v4
        with:
          name: macos-arm64-dmg
          path: ./dist/podman-desktop-*arm64.dmg
      - uses: actions/upload-artifact@v4
        with:
          name: macos-universal-dmg
          path: ./dist/podman-desktop-*universal.dmg

  website-build:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: build website
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run website
        run: pnpm website:build

      - name: Store pull request details for publish-netlify
        run: |
          echo "${{ github.event.number }}" > PR_NUMBER
          echo "${{ github.event.pull_request.head.sha }}" > PR_SHA

      - name: Upload artifact website-content
        uses: actions/upload-artifact@v4
        with:
          name: website-content
          path: |
            website/build
            PR_NUMBER
            PR_SHA

  lint-format:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: linter, formatters
    runs-on: ubuntu-24.04
    timeout-minutes: 40
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run linter
        run: pnpm lint:check

      - name: Run formatter
        run: pnpm format:check

      # Check we don't have changes in git
      - name: Check no changes in git
        run: |
          if ! git diff --exit-code; then
            echo "Found changes in git"
            exit 1
          fi

  typecheck:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: typecheck
    runs-on: ubuntu-24.04
    timeout-minutes: 40
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run typecheck
        run: pnpm typecheck

      - name: Run svelte check
        run: pnpm svelte:check

  unit-tests:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: unit tests / ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    timeout-minutes: 40
    strategy:
      fail-fast: false
      matrix:
        os: [windows-2022, ubuntu-24.04, macos-15]
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run unit tests
        run: pnpm test:unit

  smoke-e2e-tests:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: smoke e2e tests
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        mode: [production, development]
    steps:
      - uses: actions/checkout@v4

      - name: Update podman to 5.x
        run: |
          echo "ubuntu version from kubic repository to install podman we need (v5)"
          ubuntu_version='23.10'
          echo "Add unstable kubic repo into list of available sources and get the repo key"
          sudo sh -c "echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_${ubuntu_version}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list"
          curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_${ubuntu_version}/Release.key" | sudo apt-key add -
          echo "install necessary dependencies for criu package which is not part of ${ubuntu_version}"
          sudo apt-get install -qq libprotobuf32t64 python3-protobuf libnet1
          echo "install criu manually from static location"
          curl -sLO http://cz.archive.ubuntu.com/ubuntu/pool/universe/c/criu/criu_3.16.1-2_amd64.deb && sudo dpkg -i criu_3.16.1-2_amd64.deb
          echo "Updating all dependencies..."
          sudo apt-get update -qq
          echo "installing/update podman package..."
          sudo apt-get -qq -y install podman || { echo "Start fallback steps for podman nightly installation from a static mirror" && \
            sudo sh -c "echo 'deb http://ftp.lysator.liu.se/pub/opensuse/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_${ubuntu_version}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list" && \
            curl -L "http://ftp.lysator.liu.se/pub/opensuse/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_${ubuntu_version}/Release.key" | sudo apt-key add - && \
            sudo apt-get update && \
            sudo apt-get -y install podman; }
          podman version

      - name: Revert unprivileged user namespace restrictions in Ubuntu 24.04
        run: |
          # allow unprivileged user namespace
          sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

      - name: Set cgroup_manager to 'cgroupfs' instead of systemd
        run: |
          mkdir -p ~/.config/containers
          cat <<EOT >> ~/.config/containers/containers.conf
          [engine]
          cgroup_manager="cgroupfs"
          EOT
          podman info

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Run Smoke E2E tests in ${{ matrix.mode == 'production' && 'Production' || 'Development' }} Mode
        run: |
          if [ ${{ matrix.mode }} == 'production' ]; then
            echo "Compiling the Podman Desktop in production mode"
            export ELECTRON_ENABLE_INSPECT=true
            pnpm compile:current --linux dir
            path=$(realpath ./dist/linux-unpacked/podman-desktop)
            echo "Podman Desktop built binary: $path"
            export PODMAN_DESKTOP_BINARY_PATH=$path
          fi
          pnpm test:e2e:smoke

      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v5
        if: always() # always run even if the previous step fails
        with:
          fail_on_failure: true
          include_passed: true
          detailed_summary: true
          annotate_only: true
          require_tests:  true
          report_paths: '**/*results.xml'

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: ${{ matrix.mode }}-smoke-e2e-tests
          path: |
            ./tests/**/output/
            !./tests/**/traces/raw

  detect_pnpm_changes:
    if: ${{ contains(github.event.pull_request.labels.*.name, 'area/ci') || !github.event.pull_request.draft }}
    name: Detect pnpm lock or pr-check files changes
    runs-on: ubuntu-24.04
    outputs:
      pnpm_lock_changed: ${{ steps.pnpm_changed.outputs.PNPM_LOCK_CHANGED }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Evaluate changes in files
        id: pnpm_changed
        run: |
          git fetch origin ${{ github.event.pull_request.base.ref }}
          git diff --name-only origin/${{ github.event.pull_request.base.ref }} HEAD > changes.txt
          if grep -q  -e 'pnpm-lock.yaml' -e 'pr-check.yaml' changes.txt; then
            echo "PNPM_LOCK_CHANGED=true" >> $GITHUB_OUTPUT
          else
            echo "PNPM_LOCK_CHANGED=false" >> $GITHUB_OUTPUT
          fi

  win-update-e2e-test:
    name: win update e2e tests
    needs: detect_pnpm_changes
    if: contains(github.event.pull_request.labels.*.name, 'area/update') || needs.detect_pnpm_changes.outputs.pnpm_lock_changed == 'true'
    runs-on: windows-2022
    timeout-minutes: 60
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Adjust/Downgrade local podman desktop version Windows
        run: |
          $version="1.0.0"
          jq --arg version "$version" '.version = $version' package.json | Out-File -FilePath package.json_tmp
          Move-Item -Path package.json_tmp -Destination package.json -Force

      - name: Build Podman Desktop locally with electron updater included
        env:
          ELECTRON_ENABLE_INSPECT: true
        run: |
          pnpm compile:current --win nsis
          $path=('./dist/win-unpacked/Podman Desktop.exe' | resolve-path).ProviderPath
          echo $path
          echo ("PODMAN_DESKTOP_BINARY=" + $path) >> $env:GITHUB_ENV

      - name: Run E2E Update test
        run: |
          echo "${{ env.PODMAN_DESKTOP_BINARY }}"
          pnpm test:e2e:update:run

      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v5
        if: always() # always run even if the previous step fails
        with:
          fail_on_failure: true
          include_passed: true
          detailed_summary: true
          annotate_only: true
          require_tests:  true
          report_paths: '**/*results.xml'

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: win-update-e2e-test
          path: |
            ./tests/**/output/
            !./tests/**/traces/raw


  mac-update-e2e-test:
    name: mac update e2e tests
    needs: detect_pnpm_changes
    if: contains(github.event.pull_request.labels.*.name, 'area/update') || needs.detect_pnpm_changes.outputs.pnpm_lock_changed == 'true'
    runs-on: macos-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    timeout-minutes: 60
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        with:
          run_install: false

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Execute pnpm
        run: pnpm install

      - name: Adjust/Downgrade local podman desktop version
        run: |
          version="1.13.0"
          jq --arg version "$version" '.version = $version' package.json > package.json_tmp
          mv package.json_tmp package.json

      - name: Build Podman Desktop locally with electron updater included
        env:
          ELECTRON_ENABLE_INSPECT: true
        run: |
          pnpm compile:current --mac dmg
          dmgPath=$(realpath $(find ./dist -name "*.dmg"))
          echo "DMG Path: $dmgPath"
          # extract the dmg
          hdiutil attach $dmgPath
          pdVolumePath=$(find /Volumes -name *1.13.0*)
          echo "PD Volume path: $pdVolumePath"
          sudo cp -R "$pdVolumePath/Podman Desktop.app" /Applications
          # codesign the extracted app
          appPath="/Applications/Podman Desktop.app"
          sudo codesign --force --deep --sign - "$appPath"
          codesign --verify --deep --verbose=2 "$appPath"
          binaryPath="$appPath/Contents/MacOS/Podman Desktop"
          echo "PODMAN_DESKTOP_BINARY=$binaryPath" >> $GITHUB_ENV

      - name: Run E2E Update test
        env:
          UPDATE_PODMAN_DESKTOP: true
        run: |
          echo "${{ env.PODMAN_DESKTOP_BINARY }}"
          pnpm test:e2e:update:run

      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v5
        if: always() # always run even if the previous step fails
        with:
          fail_on_failure: true
          include_passed: true
          detailed_summary: true
          annotate_only: true
          require_tests:  true
          report_paths: '**/*results.xml'

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: mac-update-e2e-test
          path: |
            ./tests/**/output/
            !./tests/**/traces/raw
          
  update-e2e-test:
    name: update E2E test
    runs-on: ubuntu-24.04
    needs: [win-update-e2e-test, mac-update-e2e-test]
    if: |
      always()
    steps:
      - name: Evaluate the Windows and Mac E2E Update test results
        run: |
          echo "Windows updater result: ${{ needs.win-update-e2e-test.result }}"
          echo "Mac updater result: ${{ needs.mac-update-e2e-test.result }}"
          if [[ "${{ needs.win-update-e2e-test.result }}" = "failure" || "${{ needs.mac-update-e2e-test.result }}" = "failure" ]]; then
            echo "Windows or Mac udpater test failed..."
            exit 1
          else
            echo "Windows and Mac updater test succeeded or was skipped..."
          fi
