name: 'Cache APT Packages'
description: 'Install APT based packages and cache them for future runs.'
author: awalsh128
branding:
  icon: 'hard-drive'  
  color: 'green'

inputs:
  packages:
    description: 'Space delimited list of packages to install. Version can be specified optionally using APT command syntax of <name>=<version> (e.g. xdot=1.2-2). If not provided, packages will be read from Aptfile at repository root if it exists.'
    required: false
    default: ''
  version:
    description: 'Version of cache to load. Each version will have its own cache. Note, all characters except spaces are allowed.'
    required: false
    default: '' 
  execute_install_scripts:
    description: 'Execute Debian package pre and post install script upon restore. See README.md caveats for more information.'
    required: false
    default: 'false'
  empty_packages_behavior:
    description: >
      Desired behavior when the provided package list is empty.

      Available Options:
        error: Fail the action with an error message
        warn: Output a warning without failing the action
        ignore: Proceed silently without warnings or errors
    required: false
    default: 'error'
  refresh:
    description: 'OBSOLETE: Refresh is not used by the action, use version instead.'
    deprecationMessage: 'Refresh is not used by the action, use version instead.'
  debug:
    description: 'Enable debugging when there are issues with action. Minor performance penalty.'
    required: false
    default: 'false'
  add-repository:
    description: 'Space delimited list of repositories to add via apt-add-repository before installing packages. Supports PPA (ppa:user/repo) and other repository formats.'
    required: false
    default: ''
  use_aptfile:
    description: 'Whether to read packages from Aptfile at repository root. Set to false to disable Aptfile usage even if Aptfile exists.'
    required: false
    default: 'false'

outputs:
  cache-hit:
    description: 'A boolean value to indicate a cache was found for the packages requested.'
    # This compound expression is needed because lhs can be empty.
    # Need to output true and false instead of true and nothing.
    value: ${{ steps.load-cache.outputs.cache-hit || false }}
  package-version-list:
    description: 'The main requested packages and versions that are installed. Represented as a comma delimited list with equals delimit on the package version (i.e. <package>:<version,<package>:<version>).'
    value: ${{ steps.post-cache.outputs.package-version-list }}
  all-package-version-list:
    description: 'All the pulled in packages and versions, including dependencies, that are installed. Represented as a comma delimited list with equals delimit on the package version (i.e. <package>:<version,<package>:<version>).'
    value: ${{ steps.post-cache.outputs.all-package-version-list }}

runs:
  using: "composite"
  steps:
    - id: pre-cache
      run: | #shell
        ${GITHUB_ACTION_PATH}/pre_cache_action.sh \
          ~/cache-apt-pkgs \
          "$VERSION" \
          "$EXEC_INSTALL_SCRIPTS" \
          "$DEBUG" \
          "$ADD_REPOSITORY" \
          "$USE_APTFILE" \
          "$PACKAGES"
        if [ -f ~/cache-apt-pkgs/cache_key.md5 ]; then
          echo "CACHE_KEY=$(cat ~/cache-apt-pkgs/cache_key.md5)" >> $GITHUB_ENV
        else
          echo "CACHE_KEY=" >> $GITHUB_ENV
        fi
      shell: bash
      env:
         VERSION: "${{ inputs.version }}"
         EXEC_INSTALL_SCRIPTS: "${{ inputs.execute_install_scripts }}"
         EMPTY_PACKAGES_BEHAVIOR: "${{ inputs.empty_packages_behavior }}"
         DEBUG: "${{ inputs.debug }}"
         ADD_REPOSITORY: "${{ inputs.add-repository }}"
         USE_APTFILE: "${{ inputs.use_aptfile }}"
         PACKAGES: "${{ inputs.packages }}"

    - id: load-cache
      if: ${{ env.CACHE_KEY }}
      uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
      with:
        path: ~/cache-apt-pkgs
        key: cache-apt-pkgs_${{ env.CACHE_KEY }}

    - id: post-cache
      if: ${{ env.CACHE_KEY }}
      run: | #shell
        ${GITHUB_ACTION_PATH}/post_cache_action.sh \
          ~/cache-apt-pkgs \
          / \
          "$CACHE_HIT" \
          "$EXEC_INSTALL_SCRIPTS" \
          "$DEBUG" \
          "$ADD_REPOSITORY" \
          "$PACKAGES"
        function create_list { 
          local manifest_file="${HOME}/cache-apt-pkgs/manifest_${1}.log"
          if [ -f "${manifest_file}" ]; then
            local list=$(cat "${manifest_file}" | tr '\n' ',')
            if [ ${#list} -gt 0 ]; then
              echo ${list:0:-1}
            else
              echo ""
            fi
          else
            echo ""
          fi
        };
        echo "package-version-list=$(create_list main)" >> $GITHUB_OUTPUT
        echo "all-package-version-list=$(create_list all)" >> $GITHUB_OUTPUT
      shell: bash
      env:
         CACHE_HIT: "${{ steps.load-cache.outputs.cache-hit }}"
         EXEC_INSTALL_SCRIPTS: "${{ inputs.execute_install_scripts }}"
         DEBUG: "${{ inputs.debug }}"
         ADD_REPOSITORY: "${{ inputs.add-repository }}"
         PACKAGES: "${{ inputs.packages }}"

    - id: upload-logs
      if: ${{ env.CACHE_KEY && inputs.debug == 'true' }}
      uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
      with:
        name: cache-apt-pkgs-logs_${{ env.CACHE_KEY }}
        path: ~/cache-apt-pkgs/*.log

    - id: save-cache
      if: ${{ env.CACHE_KEY && ! steps.load-cache.outputs.cache-hit }}
      uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
      with:
        path: ~/cache-apt-pkgs
        key: ${{ steps.load-cache.outputs.cache-primary-key }}

    - id: clean-cache
      run: | #shell
        rm -rf ~/cache-apt-pkgs
      shell: bash
