cache-apt-pkgs-action icon indicating copy to clipboard operation
cache-apt-pkgs-action copied to clipboard

Fix virtual package parsing to prevent invalid cache entries

Open Copilot opened this issue 5 months ago • 2 comments

Summary

Fixed the issue where APT virtual packages with no concrete providers caused invalid package names to be cached instead of failing with a clear error message.

Changes Made

  • [x] Root Cause Analysis: Identified that virtual packages with no reverse provides (like python) return "Reverse Provides:" which gets parsed as "Reverse=Provides:" package
  • [x] Core Fix: Enhanced getNonVirtualPackage function in src/internal/common/apt.go to detect and properly handle virtual packages with no providers
  • [x] Error Handling: Action now fails with clear error message: "virtual package 'python' has no concrete package providers available"
  • [x] Consolidate Logic: Added isVirtualPackage helper function to centralize virtual package detection logic
  • [x] Fix Duplicate Messages: Removed redundant errMsgs = append(errMsgs, strings.Join(errMsgs, "\n")) line that was causing error messages to be duplicated
  • [x] Test Coverage: Added comprehensive test case TestNormalizedList_VirtualPackageWithNoProviders_StderrsErrorMessage
  • [x] Binary Updates: Rebuilt both x86 and ARM64 apt_query binaries with the fix
  • [x] Verification: Confirmed end-to-end functionality:
    • ✅ Invalid virtual packages (e.g., python) now fail with clear error (shown once, not duplicated)
    • ✅ Valid packages continue to work normally
    • ✅ Virtual packages with providers (e.g., libz-devzlib1g-dev) resolve correctly

Design Decisions

The code already automatically installs concrete packages when virtual packages have providers (preserving efficiency). When no providers exist, it fails with a clear error message to inform users they need to specify a valid package name. This approach:

  1. Maintains efficiency by auto-resolving when possible
  2. Prevents silent failures by explicitly reporting when resolution is not possible
  3. Gives users clear, actionable feedback (without message duplication)

Impact

Users will no longer experience silent failures where invalid packages get cached. Instead, they'll receive immediate, actionable error messages (shown once, clearly) when using virtual packages that have no concrete implementations.

Original prompt

This section details on the original issue you should resolve

<issue_title>APT no-installation candidates for package still saves to cache rather than failing with clear error message.</issue_title> <issue_description>I have a Github Action running daily on a private repo which tries to run some quick tests to verify an (extremely old) application is working. July 7th and prior ran fine before the latest update for the Google URL shortener removal, but July 8th and onward have failed (undetected by my checks, as my scripts were still reporting success even though the apt dependencies were not present. oops).

It seems to be failing because of the - Reverse=Provides: line is erroneously detecting as a package to install. E: Unable to locate package Reverse.

I have tried to update my Action to use Ubuntu v24.04 but unfortunately the application code I am running has not been touched since ~2019ish and thus there are build errors on newer Ubuntu versions that are a headache for another day. I am hoping there could be a quick fix for this so that I can continue caching my apt installs without having to touch ~30 year old C/C++ code 🙏.

Here is the relevant part of my ci.yml:

jobs:
  build-and-test:
    runs-on: ubuntu-22.04
    steps:
    - name: Checkout Repository
      uses: actions/checkout@v4
      with:
        fetch-depth: 0
        submodules: true

    - name: Install Packages
      uses: awalsh128/cache-apt-pkgs-action@latest
      with:
        packages: build-essential telnet expect git python bison \
          autoconf automake autogen libevent-dev libjemalloc-dev \
          default-libmysqlclient-dev libpcre3-dev libpq-dev libsqlite3-dev \
          libssl-dev libz-dev libgtest-dev
        version: 1.0
July 8th run

Run awalsh128/cache-apt-pkgs-action@latest
  with:
    packages: build-essential telnet expect git python bison \ autoconf automake autogen libevent-dev libjemalloc-dev \ default-libmysqlclient-dev libpcre3-dev libpq-dev libsqlite3-dev \ libssl-dev libz-dev libgtest-dev
    version: 1
    execute_install_scripts: false
    debug: false
Run ${GITHUB_ACTION_PATH}/pre_cache_action.sh \
  ${GITHUB_ACTION_PATH}/pre_cache_action.sh \
    ~/cache-apt-pkgs \
    "$VERSION" \
    "$EXEC_INSTALL_SCRIPTS" \
    "$DEBUG" \
    "$PACKAGES"
  echo "CACHE_KEY=$(cat ~/cache-apt-pkgs/cache_key.md5)" >> $GITHUB_ENV
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    VERSION: 1
    EXEC_INSTALL_SCRIPTS: false
    DEBUG: false
    PACKAGES: build-essential telnet expect git python bison \ autoconf automake autogen libevent-dev libjemalloc-dev \ default-libmysqlclient-dev libpcre3-dev libpq-dev libsqlite3-dev \ libssl-dev libz-dev libgtest-dev
Normalizing package list...
done
Validating action arguments (version='1', packages='Reverse=Provides: autoconf=2.71-2 autogen=1:5.18.16-4 automake=1:1.16.5-1.3 bison=2:3.8.2+dfsg-1build1 build-essential=12.9ubuntu3 default-libmysqlclient-dev=1.0.8 expect=5.45.4-2build1 git=1:2.49.0-2~ppa1~ubuntu22.04.1 libevent-dev=2.1.12-stable-1build3 libgtest-dev=1.11.0-3 libjemalloc-dev=5.2.1-4ubuntu1 libpcre3-dev=2:8.39-13ubuntu0.22.04.1 libpq-dev=17.5-1.pgdg22.04+1 libsqlite3-dev=3.37.2-2ubuntu0.4 libssl-dev=3.0.2-0ubuntu1.19 telnet=0.17-44build1')...
done

Creating cache key...
- Value to hash is 'Reverse=Provides: autoconf=2.71-2 autogen=1:5.18.16-4 automake=1:1.16.5-1.3 bison=2:3.8.2+dfsg-1build1 build-essential=12.9ubuntu3 default-libmysqlclient-dev=1.0.8 expect=5.45.4-2build1 git=1:2.49.0-2~ppa1~ubuntu22.04.1 libevent-dev=2.1.12-stable-1build3 libgtest-dev=1.11.0-3 libjemalloc-dev=5.2.1-4ubuntu1 libpcre3-dev=2:8.39-13ubuntu0.22.04.1 libpq-dev=17.5-1.pgdg22.04+1 libsqlite3-dev=3.37.2-2ubuntu0.4 libssl-dev=3.0.2-0ubuntu1.19 telnet=0.17-44build1 @ 1 3'.
- Value hashed as '68dff83ef6c4bb3671c78ab4e04a9cf1'.
done
Hash value written to /home/runner/cache-apt-pkgs/cache_key.md5
Run actions/cache/restore@v4
Cache not found for input keys: cache-apt-pkgs_68dff83ef6c4bb3671c78ab4e04a9cf1
Run ${GITHUB_ACTION_PATH}/post_cache_action.sh \
Updating APT package list...
done

Clean installing and caching 17 package(s).

Package list:
- Reverse=Provides:
- autoconf=2.71-2
- autogen=1:5.18.16-4
- automake=1:1.16.5-1.3
- bison=2:3.8.2+dfsg-1build1
- build-essential=12.9ubuntu3
- default-libmysqlclient-dev=1.0.8
- expect=5.45.4-2build1
- git=1:2.49.0-2~ppa1~ubuntu22.04.1
- libevent-dev=2.1.12-stable-1build3
- libgtest-dev=1.11.0-3
- libjemalloc-dev=5.2.1-4ubuntu1
- libpcre3-dev=2:8.39-13ubuntu0.22.04.1
- libpq-dev=17.5-1.pgdg22.04+1
- libsqlite3-dev=3.37.2-2ubuntu0.4
- libssl-dev=3.0.2-0ubuntu1.19
- telnet=0.17-44build1
Writing main packages manifest to /home/runner/cache-apt-pkgs/manifest_main.log...
done

Clean installing 17 packages...
E: Unable to locate package Reverse
[apt-fast 12:47:24]Package manager quit with exit code.
done
Installation log written to /home/runner/cache-apt-pkgs/install.log

Installed package list:

Caching 0...

</details>
Fixes awalsh128/cache-apt-pkgs-action#166

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start the survey.

Copilot avatar Sep 30 '25 07:09 Copilot