diff --git a/.github/workflows/maintain_cache.yml b/.github/workflows/maintain_cache.yml new file mode 100644 index 000000000..0e82c6114 --- /dev/null +++ b/.github/workflows/maintain_cache.yml @@ -0,0 +1,82 @@ +name: Garak maintain cache + +on: + push: + branches: + - 'main' + paths-ignore: + - 'garak/resources/plugin_cache.json' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + # forcing full checkout for reflog access + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.12" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Build a local cache + run: | + export TZ=UTC + git ls-files garak/ -z | xargs -0 -I{} -- git log -1 --date=iso-local --format="%ad {}" {} | while read -r udate utime utz ufile ; do + touch -d "$udate $utime" $ufile + done + python -m garak --list_probes + - name: Commit updated plugin cache if modified + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILE_TO_COMMIT: garak/resources/plugin_cache.json + DESTINATION_BRANCH: ${{ github.ref_name }} + COMMIT_RESULT: ${{ endsWith(github.ref_name, '/main')}} + run: | + if [ -f $HOME/.cache/garak/resources/plugin_cache.json ]; then + echo "File updated from user cache" + cp $HOME/.cache/garak/resources/plugin_cache.json $FILE_TO_COMMIT + cat $HOME/.local/share/garak/garak.log + fi + set +e + git diff --exit-code $FILE_TO_COMMIT > /dev/null + if [ $? -ne 0 ]; then + set -e + echo "Plugin cache updates exist" + if [ "$COMMIT_RESULT" = true ]; then + export MESSAGE="automatic $FILE_TO_COMMIT update" + export SHA=$( git rev-parse $DESTINATION_BRANCH:$FILE_TO_COMMIT ) + cat <<- EOF > write_request.py + #!python + import json + import os + import base64 + with open("$FILE_TO_COMMIT", 'rb') as f: + content = base64.b64encode(f.read()).decode() + request = { + "message": os.environ["MESSAGE"], + "content": content, + "encoding": "base64", + "branch": os.environ["DESTINATION_BRANCH"], + "sha": os.environ["SHA"], + } + with open("request.json", "w", encoding="utf-8") as f: + json.dump(request, f, indent=4) + EOF + chmod +x write_request.py + python write_request.py + gh api --method PUT /repos/:owner/:repo/contents/$FILE_TO_COMMIT --input request.json + echo "Update committed to repo" + fi + else + echo "No Plugin cache updates exit without commit" + fi \ No newline at end of file diff --git a/garak/_plugins.py b/garak/_plugins.py index e805e8745..8ea4a11f2 100644 --- a/garak/_plugins.py +++ b/garak/_plugins.py @@ -103,7 +103,8 @@ def _valid_loaded_cache(self, local_cache, user_time): for plugin_type in PLUGIN_TYPES: validated_plugin_filenames = set() prev_mod = None - for k in local_cache[plugin_type]: + plugins = local_cache.get(plugin_type, {}) + for k in plugins: category, module, klass = k.split(".") if module != prev_mod: prev_mod = module @@ -125,7 +126,7 @@ def _valid_loaded_cache(self, local_cache, user_time): # if all known are up-to-date check filesystem for missing found_filenames = set() - plugin_path = _config.transient.package_dir / category + plugin_path = _config.transient.package_dir / plugin_type for module_filename in sorted(os.listdir(plugin_path)): if not module_filename.endswith(".py"): continue