diff --git a/.changeset/patch-configurable-memory-file-types.md b/.changeset/patch-configurable-memory-file-types.md new file mode 100644 index 0000000000..7e11d491ce --- /dev/null +++ b/.changeset/patch-configurable-memory-file-types.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Add configurable allowed extensions for cache-memory and repo-memory along with validation failure reporting diff --git a/.changeset/patch-configure-memory-extensions.md b/.changeset/patch-configure-memory-extensions.md new file mode 100644 index 0000000000..f991752b3f --- /dev/null +++ b/.changeset/patch-configure-memory-extensions.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Documented cache-memory and repo-memory now support configuring allowed extensions, expose the defaults, and surface validation failures when invalid files are detected. diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index 0413dd1111..c369c67363 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -692,6 +692,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: ** @@ -700,10 +701,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -1054,6 +1058,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1243,6 +1249,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1277,6 +1286,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1288,6 +1298,7 @@ jobs: BRANCH_NAME: memory/meta-orchestrators MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "**" with: script: | diff --git a/.github/workflows/agent-persona-explorer.lock.yml b/.github/workflows/agent-persona-explorer.lock.yml index c886ab4097..5d0e5a0a7e 100644 --- a/.github/workflows/agent-persona-explorer.lock.yml +++ b/.github/workflows/agent-persona-explorer.lock.yml @@ -634,6 +634,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -652,6 +653,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -823,6 +825,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1186,6 +1201,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index 79afe897c0..9dff4bf155 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -651,6 +651,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/audit-workflows/*.json, memory/audit-workflows/*.jsonl, memory/audit-workflows/*.csv, memory/audit-workflows/*.md @@ -659,10 +660,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -730,6 +734,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -748,6 +753,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -982,6 +988,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1097,6 +1116,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1273,6 +1294,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1307,6 +1331,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1318,6 +1343,7 @@ jobs: BRANCH_NAME: memory/audit-workflows MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/audit-workflows/*.json memory/audit-workflows/*.jsonl memory/audit-workflows/*.csv memory/audit-workflows/*.md" with: script: | @@ -1408,6 +1434,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/chroma-issue-indexer.lock.yml b/.github/workflows/chroma-issue-indexer.lock.yml index 6482007bdd..ee0219e390 100644 --- a/.github/workflows/chroma-issue-indexer.lock.yml +++ b/.github/workflows/chroma-issue-indexer.lock.yml @@ -293,28 +293,8 @@ jobs: GH_AW_PROMPT_EOF cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" + cat "/opt/gh-aw/prompts/cache_memory_prompt_multi.md" >> "$GH_AW_PROMPT" cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - --- - - ## Cache Folders Available - - You have access to persistent cache folders where you can read and write files to create memories and store information: - - - **chroma**: `/tmp/gh-aw/cache-memory-chroma/` - Persistent storage for Chroma vector database - - - **Read/Write Access**: You can freely read from and write to any files in these folders - - **Persistence**: Files in these folders persist across workflow runs via GitHub Actions cache - - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved - - **File Share**: Use these as simple file shares - organize files as you see fit - - Examples of what you can store: - - `/tmp/gh-aw/cache-memory-chroma/notes.txt` - general notes and observations - - `/tmp/gh-aw/cache-memory-chroma/preferences.json` - user preferences and settings - - `/tmp/gh-aw/cache-memory-chroma/state/` - organized state files in subdirectories - - Feel free to create, read, update, and organize files in these folders as needed for your tasks. - The following GitHub context information is available for this workflow: {{#if __GH_AW_GITHUB_ACTOR__ }} @@ -360,6 +340,16 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' + GH_AW_CACHE_EXAMPLES: '- `/tmp/gh-aw/cache-memory-chroma/notes.txt` - general notes and observations +- `/tmp/gh-aw/cache-memory-chroma/notes.md` - markdown formatted notes +- `/tmp/gh-aw/cache-memory-chroma/preferences.json` - user preferences and settings +- `/tmp/gh-aw/cache-memory-chroma/history.jsonl` - activity history in JSON Lines format +- `/tmp/gh-aw/cache-memory-chroma/data.csv` - tabular data +- `/tmp/gh-aw/cache-memory-chroma/state/` - organized state files in subdirectories (with allowed file types) +' + GH_AW_CACHE_LIST: '- **chroma**: `/tmp/gh-aw/cache-memory-chroma/` - Persistent storage for Chroma vector database +' GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} @@ -376,6 +366,9 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, + GH_AW_CACHE_EXAMPLES: process.env.GH_AW_CACHE_EXAMPLES, + GH_AW_CACHE_LIST: process.env.GH_AW_CACHE_LIST, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, @@ -515,6 +508,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types (chroma) + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory-chroma', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload agent artifacts if: always() continue-on-error: true diff --git a/.github/workflows/ci-coach.lock.yml b/.github/workflows/ci-coach.lock.yml index 2aa9112eef..685d8d220d 100644 --- a/.github/workflows/ci-coach.lock.yml +++ b/.github/workflows/ci-coach.lock.yml @@ -625,6 +625,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -644,6 +645,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -818,6 +820,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1198,6 +1213,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 7a335a23fd..b34124be7a 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -726,6 +726,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -750,6 +751,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -933,6 +935,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1321,6 +1336,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/claude-code-user-docs-review.lock.yml b/.github/workflows/claude-code-user-docs-review.lock.yml index 0acd6caacc..8dcf1276ef 100644 --- a/.github/workflows/claude-code-user-docs-review.lock.yml +++ b/.github/workflows/claude-code-user-docs-review.lock.yml @@ -564,6 +564,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -582,6 +583,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -805,6 +807,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1159,6 +1174,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index a6b2f0ca50..05e589214e 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -595,6 +595,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -613,6 +614,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -836,6 +838,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1181,6 +1196,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 28056e2072..d10dc0daa1 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -794,6 +794,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -818,6 +819,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1098,6 +1100,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1563,6 +1578,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/code-scanning-fixer.lock.yml b/.github/workflows/code-scanning-fixer.lock.yml index e197541b9b..b8545ad97e 100644 --- a/.github/workflows/code-scanning-fixer.lock.yml +++ b/.github/workflows/code-scanning-fixer.lock.yml @@ -571,13 +571,17 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. Examples of what you can store: - `/tmp/gh-aw/repo-memory/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/history/` - organized history files + - `/tmp/gh-aw/repo-memory/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/history/` - organized history files (with allowed file types) - Feel free to create, read, update, and organize files in these folders as needed for your tasks. + Feel free to create, read, update, and organize files in these folders as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -636,6 +640,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -654,6 +659,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -834,6 +840,19 @@ jobs: path: /tmp/gh-aw/repo-memory/campaigns retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -935,6 +954,8 @@ jobs: GH_AW_WORKFLOW_ID: "code-scanning-fixer" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_campaigns: ${{ needs.push_repo_memory.outputs.validation_failed_campaigns }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_campaigns: ${{ needs.push_repo_memory.outputs.validation_error_campaigns }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1151,6 +1172,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_campaigns: ${{ steps.push_repo_memory_campaigns.outputs.validation_error }} + validation_failed_campaigns: ${{ steps.push_repo_memory_campaigns.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1185,6 +1209,7 @@ jobs: name: repo-memory-campaigns path: /tmp/gh-aw/repo-memory/campaigns - name: Push repo-memory changes (campaigns) + id: push_repo_memory_campaigns if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1196,6 +1221,7 @@ jobs: BRANCH_NAME: memory/campaigns MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "security-alert-burndown/**" with: script: | @@ -1312,6 +1338,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml index f02da153fc..9dabd98767 100644 --- a/.github/workflows/copilot-agent-analysis.lock.yml +++ b/.github/workflows/copilot-agent-analysis.lock.yml @@ -539,6 +539,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/copilot-agent-analysis/*.json, memory/copilot-agent-analysis/*.jsonl, memory/copilot-agent-analysis/*.csv, memory/copilot-agent-analysis/*.md @@ -547,10 +548,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -618,6 +622,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -636,6 +641,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -891,6 +897,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -993,6 +1012,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1167,6 +1188,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1201,6 +1225,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1212,6 +1237,7 @@ jobs: BRANCH_NAME: memory/copilot-agent-analysis MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/copilot-agent-analysis/*.json memory/copilot-agent-analysis/*.jsonl memory/copilot-agent-analysis/*.csv memory/copilot-agent-analysis/*.md" with: script: | @@ -1301,6 +1327,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/copilot-cli-deep-research.lock.yml b/.github/workflows/copilot-cli-deep-research.lock.yml index 81093ff89f..3d724403fa 100644 --- a/.github/workflows/copilot-cli-deep-research.lock.yml +++ b/.github/workflows/copilot-cli-deep-research.lock.yml @@ -515,6 +515,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/copilot-cli-research/*.json, memory/copilot-cli-research/*.md @@ -523,10 +524,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -902,6 +906,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1061,6 +1067,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1095,6 +1104,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1106,6 +1116,7 @@ jobs: BRANCH_NAME: memory/copilot-cli-research MAX_FILE_SIZE: 204800 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/copilot-cli-research/*.json memory/copilot-cli-research/*.md" with: script: | diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index 3965e67aa3..cb4bc68002 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -593,6 +593,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/nlp-analysis/*.json, memory/nlp-analysis/*.jsonl, memory/nlp-analysis/*.csv, memory/nlp-analysis/*.md @@ -601,10 +602,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -675,6 +679,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -693,6 +698,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -878,6 +884,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -990,6 +1009,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1149,6 +1170,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1183,6 +1207,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1194,6 +1219,7 @@ jobs: BRANCH_NAME: memory/nlp-analysis MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/nlp-analysis/*.json memory/nlp-analysis/*.jsonl memory/nlp-analysis/*.csv memory/nlp-analysis/*.md" with: script: | @@ -1283,6 +1309,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml index b3a6ce97ce..664abb744f 100644 --- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml +++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml @@ -535,6 +535,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/prompt-analysis/*.json, memory/prompt-analysis/*.jsonl, memory/prompt-analysis/*.csv, memory/prompt-analysis/*.md @@ -543,10 +544,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -614,6 +618,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -632,6 +637,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -814,6 +820,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -916,6 +935,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1075,6 +1096,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1109,6 +1133,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1120,6 +1145,7 @@ jobs: BRANCH_NAME: memory/prompt-analysis MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/prompt-analysis/*.json memory/prompt-analysis/*.jsonl memory/prompt-analysis/*.csv memory/prompt-analysis/*.md" with: script: | @@ -1209,6 +1235,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index 184fe22c2a..9ed7be1bcc 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -594,6 +594,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/session-insights/*.json, memory/session-insights/*.jsonl, memory/session-insights/*.csv, memory/session-insights/*.md @@ -602,10 +603,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -682,6 +686,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -701,6 +706,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -937,6 +943,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1049,6 +1068,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1223,6 +1244,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1257,6 +1281,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1268,6 +1293,7 @@ jobs: BRANCH_NAME: memory/session-insights MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/session-insights/*.json memory/session-insights/*.jsonl memory/session-insights/*.csv memory/session-insights/*.md" with: script: | @@ -1357,6 +1383,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index 988a490c3e..d7e724a927 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -705,6 +705,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/cli-performance/*.json, memory/cli-performance/*.jsonl, memory/cli-performance/*.txt @@ -713,10 +714,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -1086,6 +1090,8 @@ jobs: GH_AW_WORKFLOW_ID: "daily-cli-performance" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1247,6 +1253,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1281,6 +1290,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1292,6 +1302,7 @@ jobs: BRANCH_NAME: memory/cli-performance MAX_FILE_SIZE: 512000 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/cli-performance/*.json memory/cli-performance/*.jsonl memory/cli-performance/*.txt" with: script: | diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index 242c00b995..959341d554 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -582,6 +582,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: *.json, *.jsonl, *.csv, *.md @@ -590,10 +591,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -661,6 +665,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -679,6 +684,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -911,6 +917,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1026,6 +1045,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1202,6 +1223,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1236,6 +1260,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1247,6 +1272,7 @@ jobs: BRANCH_NAME: daily/default MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "*.json *.jsonl *.csv *.md" with: script: | @@ -1337,6 +1363,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-compiler-quality.lock.yml b/.github/workflows/daily-compiler-quality.lock.yml index 053ad05728..f67068579c 100644 --- a/.github/workflows/daily-compiler-quality.lock.yml +++ b/.github/workflows/daily-compiler-quality.lock.yml @@ -571,6 +571,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -589,6 +590,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -782,6 +784,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1121,6 +1136,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index bf02fc26a0..568fd9629b 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -611,6 +611,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/token-metrics/*.json, memory/token-metrics/*.jsonl, memory/token-metrics/*.csv, memory/token-metrics/*.md @@ -619,10 +620,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -687,6 +691,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -705,6 +710,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -889,6 +895,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1004,6 +1023,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1165,6 +1186,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1199,6 +1223,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1210,6 +1235,7 @@ jobs: BRANCH_NAME: memory/token-metrics MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/token-metrics/*.json memory/token-metrics/*.jsonl memory/token-metrics/*.csv memory/token-metrics/*.md" with: script: | @@ -1300,6 +1326,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-doc-updater.lock.yml b/.github/workflows/daily-doc-updater.lock.yml index 5ab9d20744..95d5f75b48 100644 --- a/.github/workflows/daily-doc-updater.lock.yml +++ b/.github/workflows/daily-doc-updater.lock.yml @@ -573,6 +573,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -591,6 +592,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -835,6 +837,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1230,6 +1245,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml index 99b70bdf8d..d8916b2f47 100644 --- a/.github/workflows/daily-firewall-report.lock.yml +++ b/.github/workflows/daily-firewall-report.lock.yml @@ -689,6 +689,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -707,6 +708,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -881,6 +883,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1230,6 +1245,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index 772813a625..5f2718ea8d 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -717,6 +717,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -735,6 +736,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -891,6 +893,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1262,6 +1277,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-mcp-concurrency-analysis.lock.yml b/.github/workflows/daily-mcp-concurrency-analysis.lock.yml index 4aad51a877..a927470497 100644 --- a/.github/workflows/daily-mcp-concurrency-analysis.lock.yml +++ b/.github/workflows/daily-mcp-concurrency-analysis.lock.yml @@ -623,6 +623,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -641,6 +642,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -835,6 +837,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1185,6 +1200,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index 0cabe98c04..99623d46e1 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -663,6 +663,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/daily-news/*.json, memory/daily-news/*.jsonl, memory/daily-news/*.csv, memory/daily-news/*.md @@ -671,10 +672,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -748,6 +752,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -766,6 +771,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -951,6 +957,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1066,6 +1085,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1227,6 +1248,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1261,6 +1285,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1272,6 +1297,7 @@ jobs: BRANCH_NAME: memory/daily-news MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/daily-news/*.json memory/daily-news/*.jsonl memory/daily-news/*.csv memory/daily-news/*.md" with: script: | @@ -1362,6 +1388,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml index 6f645ed519..1db0cd3ede 100644 --- a/.github/workflows/daily-performance-summary.lock.yml +++ b/.github/workflows/daily-performance-summary.lock.yml @@ -1182,6 +1182,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -1200,6 +1201,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1365,6 +1367,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1707,6 +1722,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-repo-chronicle.lock.yml b/.github/workflows/daily-repo-chronicle.lock.yml index b22e2f71dc..ac7813fe68 100644 --- a/.github/workflows/daily-repo-chronicle.lock.yml +++ b/.github/workflows/daily-repo-chronicle.lock.yml @@ -623,6 +623,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -641,6 +642,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -816,6 +818,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1165,6 +1180,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-safe-output-optimizer.lock.yml b/.github/workflows/daily-safe-output-optimizer.lock.yml index 18f2515bb8..5945081dfe 100644 --- a/.github/workflows/daily-safe-output-optimizer.lock.yml +++ b/.github/workflows/daily-safe-output-optimizer.lock.yml @@ -669,6 +669,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -687,6 +688,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -922,6 +924,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1310,6 +1325,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/daily-testify-uber-super-expert.lock.yml b/.github/workflows/daily-testify-uber-super-expert.lock.yml index 71c971dd34..10a42568c0 100644 --- a/.github/workflows/daily-testify-uber-super-expert.lock.yml +++ b/.github/workflows/daily-testify-uber-super-expert.lock.yml @@ -546,6 +546,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/testify-expert/*.json, memory/testify-expert/*.txt @@ -554,10 +555,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -934,6 +938,8 @@ jobs: GH_AW_WORKFLOW_ID: "daily-testify-uber-super-expert" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1138,6 +1144,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1172,6 +1181,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1183,6 +1193,7 @@ jobs: BRANCH_NAME: memory/testify-expert MAX_FILE_SIZE: 51200 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/testify-expert/*.json memory/testify-expert/*.txt" with: script: | diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 6ba826a8f7..87f51649a8 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -738,6 +738,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/deep-report/*.md @@ -746,10 +747,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -817,6 +821,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -835,6 +840,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -998,6 +1004,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1113,6 +1132,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1266,6 +1287,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1300,6 +1324,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1311,6 +1336,7 @@ jobs: BRANCH_NAME: memory/deep-report MAX_FILE_SIZE: 1048576 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/deep-report/*.md" with: script: | @@ -1401,6 +1427,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml index 17afb0c02d..422dd815b4 100644 --- a/.github/workflows/delight.lock.yml +++ b/.github/workflows/delight.lock.yml @@ -591,6 +591,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/delight/*.json, memory/delight/*.md @@ -599,10 +600,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -984,6 +988,8 @@ jobs: GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📊 *User experience analysis by [{workflow_name}]({run_url})*\",\"runStarted\":\"📊 Delight Agent starting! [{workflow_name}]({run_url}) is analyzing user-facing aspects for improvement opportunities...\",\"runSuccess\":\"✅ Analysis complete! [{workflow_name}]({run_url}) has identified targeted improvements for user experience.\",\"runFailure\":\"⚠️ Analysis interrupted! [{workflow_name}]({run_url}) {status}. Please review the logs...\"}" + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1146,6 +1152,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1180,6 +1189,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1191,6 +1201,7 @@ jobs: BRANCH_NAME: memory/delight MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/delight/*.json memory/delight/*.md" with: script: | diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index b8a3a0e8fa..a502ec97e8 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -646,6 +646,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -664,6 +665,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -910,6 +912,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1301,6 +1316,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index 6e2239ed30..c4608f7082 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -563,6 +563,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/discussion-task-miner/*.json, memory/discussion-task-miner/*.md @@ -571,10 +572,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -950,6 +954,8 @@ jobs: GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔍 *Task mining by [{workflow_name}]({run_url})*\",\"runStarted\":\"🔍 Discussion Task Miner starting! [{workflow_name}]({run_url}) is scanning discussions for code quality improvements...\",\"runSuccess\":\"✅ Task mining complete! [{workflow_name}]({run_url}) has identified actionable code quality tasks. 📊\",\"runFailure\":\"⚠️ Task mining interrupted! [{workflow_name}]({run_url}) {status}. Please review the logs...\"}" + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1112,6 +1118,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1146,6 +1155,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1157,6 +1167,7 @@ jobs: BRANCH_NAME: memory/discussion-task-miner MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/discussion-task-miner/*.json memory/discussion-task-miner/*.md" with: script: | diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml index 8bcdc41a2a..7aa848d84b 100644 --- a/.github/workflows/firewall-escape.lock.yml +++ b/.github/workflows/firewall-escape.lock.yml @@ -533,6 +533,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Max File Size**: 524288 bytes (0.50 MB) per file @@ -540,10 +541,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -602,6 +606,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -620,6 +625,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -801,6 +807,19 @@ jobs: path: /tmp/gh-aw/repo-memory/default retention-days: 1 if-no-files-found: ignore + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -906,6 +925,8 @@ jobs: GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_CREATE_DISCUSSION_ERRORS: ${{ needs.safe_outputs.outputs.create_discussion_errors }} GH_AW_CREATE_DISCUSSION_ERROR_COUNT: ${{ needs.safe_outputs.outputs.create_discussion_error_count }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1127,6 +1148,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1161,6 +1185,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1172,6 +1197,7 @@ jobs: BRANCH_NAME: memory/firewall-escape MAX_FILE_SIZE: 524288 MAX_FILE_COUNT: 50 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' with: script: | const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); @@ -1261,6 +1287,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml index 7a0b782cac..d9f2d827cf 100644 --- a/.github/workflows/github-mcp-structural-analysis.lock.yml +++ b/.github/workflows/github-mcp-structural-analysis.lock.yml @@ -625,6 +625,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -643,6 +644,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -868,6 +870,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1226,6 +1241,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml index 7906845a03..039e13e5b0 100644 --- a/.github/workflows/github-mcp-tools-report.lock.yml +++ b/.github/workflows/github-mcp-tools-report.lock.yml @@ -633,6 +633,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -651,6 +652,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -872,6 +874,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1263,6 +1278,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 72fe80e011..39bcf51662 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -596,6 +596,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -614,6 +615,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -813,6 +815,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1186,6 +1201,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml index c3f21d8011..ca81bd97ce 100644 --- a/.github/workflows/go-fan.lock.yml +++ b/.github/workflows/go-fan.lock.yml @@ -583,6 +583,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -601,6 +602,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -842,6 +844,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1196,6 +1211,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/go-logger.lock.yml b/.github/workflows/go-logger.lock.yml index efdb922f03..b257112908 100644 --- a/.github/workflows/go-logger.lock.yml +++ b/.github/workflows/go-logger.lock.yml @@ -727,6 +727,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -745,6 +746,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1001,6 +1003,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1390,6 +1405,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/gpclean.lock.yml b/.github/workflows/gpclean.lock.yml index 56c5a6d6c6..312a1d7899 100644 --- a/.github/workflows/gpclean.lock.yml +++ b/.github/workflows/gpclean.lock.yml @@ -586,6 +586,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -604,6 +605,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -776,6 +778,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1106,6 +1121,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 4b68ebb815..3784645269 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -647,6 +647,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -667,6 +668,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -844,6 +846,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1239,6 +1254,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/instructions-janitor.lock.yml b/.github/workflows/instructions-janitor.lock.yml index 74bddd11f7..09cb40bbc7 100644 --- a/.github/workflows/instructions-janitor.lock.yml +++ b/.github/workflows/instructions-janitor.lock.yml @@ -573,6 +573,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -591,6 +592,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -834,6 +836,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1222,6 +1237,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/jsweep.lock.yml b/.github/workflows/jsweep.lock.yml index b398939b9f..9c20f031ea 100644 --- a/.github/workflows/jsweep.lock.yml +++ b/.github/workflows/jsweep.lock.yml @@ -587,6 +587,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -605,6 +606,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -778,6 +780,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1158,6 +1173,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml index aca5f08710..7d902b2b0f 100644 --- a/.github/workflows/lockfile-stats.lock.yml +++ b/.github/workflows/lockfile-stats.lock.yml @@ -567,6 +567,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -585,6 +586,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -806,6 +808,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1154,6 +1169,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 4f61568b99..46c4a01674 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -931,6 +931,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -949,6 +950,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1136,6 +1138,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1745,6 +1760,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/metrics-collector.lock.yml b/.github/workflows/metrics-collector.lock.yml index 209c076921..b6d6ec54e9 100644 --- a/.github/workflows/metrics-collector.lock.yml +++ b/.github/workflows/metrics-collector.lock.yml @@ -353,6 +353,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: metrics/** @@ -361,10 +362,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. The following GitHub context information is available for this workflow: @@ -625,6 +629,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -659,6 +666,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -670,6 +678,7 @@ jobs: BRANCH_NAME: memory/meta-orchestrators MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "metrics/**" with: script: | diff --git a/.github/workflows/org-health-report.lock.yml b/.github/workflows/org-health-report.lock.yml index 6b075a6678..01b063c2f8 100644 --- a/.github/workflows/org-health-report.lock.yml +++ b/.github/workflows/org-health-report.lock.yml @@ -616,6 +616,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -634,6 +635,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -808,6 +810,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1151,6 +1166,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 1d1409b9dc..ef49e198a9 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -665,6 +665,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_799BE623: ${{ github.event.issue.number || github.event.pull_request.number }} @@ -688,6 +689,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_799BE623: process.env.GH_AW_EXPR_799BE623, @@ -871,6 +873,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1270,6 +1285,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 640f03c8f9..6edfee9260 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -1151,6 +1151,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -1172,6 +1173,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1377,6 +1379,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1845,6 +1860,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/portfolio-analyst.lock.yml b/.github/workflows/portfolio-analyst.lock.yml index 7a5dad7224..cce2496c08 100644 --- a/.github/workflows/portfolio-analyst.lock.yml +++ b/.github/workflows/portfolio-analyst.lock.yml @@ -699,6 +699,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -717,6 +718,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -892,6 +894,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1241,6 +1256,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 7cc40dd789..6605482e04 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -727,6 +727,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -747,6 +748,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -925,6 +927,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1328,6 +1343,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index d33be36f3e..9915af17da 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -592,6 +592,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: ** @@ -600,10 +601,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -952,6 +956,8 @@ jobs: GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"runStarted\":\"🔍 Starting PR triage analysis... [{workflow_name}]({run_url}) is categorizing and prioritizing agent-created PRs\",\"runSuccess\":\"✅ PR triage complete! [{workflow_name}]({run_url}) has analyzed and categorized PRs. Check the issue for detailed report.\",\"runFailure\":\"❌ PR triage failed! [{workflow_name}]({run_url}) {status}. Some PRs may not be triaged.\"}" + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1112,6 +1118,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1146,6 +1155,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1157,6 +1167,7 @@ jobs: BRANCH_NAME: memory/pr-triage MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "**" with: script: | diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index f9c93fa1ac..85cc36e6a3 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -698,6 +698,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -716,6 +717,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -937,6 +939,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1285,6 +1300,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml index 54cc91a74e..0f0f3ab3c2 100644 --- a/.github/workflows/python-data-charts.lock.yml +++ b/.github/workflows/python-data-charts.lock.yml @@ -688,6 +688,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -706,6 +707,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -882,6 +884,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1225,6 +1240,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 98005b6576..50ed08d561 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -748,6 +748,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_799BE623: ${{ github.event.issue.number || github.event.pull_request.number }} @@ -769,6 +770,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_799BE623: process.env.GH_AW_EXPR_799BE623, @@ -951,6 +953,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1396,6 +1411,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/repo-audit-analyzer.lock.yml b/.github/workflows/repo-audit-analyzer.lock.yml index 23d061fdc4..dfda5643c0 100644 --- a/.github/workflows/repo-audit-analyzer.lock.yml +++ b/.github/workflows/repo-audit-analyzer.lock.yml @@ -507,28 +507,8 @@ jobs: GH_AW_PROMPT_EOF cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" + cat "/opt/gh-aw/prompts/cache_memory_prompt_multi.md" >> "$GH_AW_PROMPT" cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - --- - - ## Cache Folders Available - - You have access to persistent cache folders where you can read and write files to create memories and store information: - - - **repo-audits**: `/tmp/gh-aw/cache-memory-repo-audits/` - - - **Read/Write Access**: You can freely read from and write to any files in these folders - - **Persistence**: Files in these folders persist across workflow runs via GitHub Actions cache - - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved - - **File Share**: Use these as simple file shares - organize files as you see fit - - Examples of what you can store: - - `/tmp/gh-aw/cache-memory-repo-audits/notes.txt` - general notes and observations - - `/tmp/gh-aw/cache-memory-repo-audits/preferences.json` - user preferences and settings - - `/tmp/gh-aw/cache-memory-repo-audits/state/` - organized state files in subdirectories - - Feel free to create, read, update, and organize files in these folders as needed for your tasks. - GitHub API Access Instructions @@ -589,6 +569,16 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' + GH_AW_CACHE_EXAMPLES: '- `/tmp/gh-aw/cache-memory-repo-audits/notes.txt` - general notes and observations +- `/tmp/gh-aw/cache-memory-repo-audits/notes.md` - markdown formatted notes +- `/tmp/gh-aw/cache-memory-repo-audits/preferences.json` - user preferences and settings +- `/tmp/gh-aw/cache-memory-repo-audits/history.jsonl` - activity history in JSON Lines format +- `/tmp/gh-aw/cache-memory-repo-audits/data.csv` - tabular data +- `/tmp/gh-aw/cache-memory-repo-audits/state/` - organized state files in subdirectories (with allowed file types) +' + GH_AW_CACHE_LIST: '- **repo-audits**: `/tmp/gh-aw/cache-memory-repo-audits/` +' GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} @@ -606,6 +596,9 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, + GH_AW_CACHE_EXAMPLES: process.env.GH_AW_CACHE_EXAMPLES, + GH_AW_CACHE_LIST: process.env.GH_AW_CACHE_LIST, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, @@ -777,6 +770,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types (repo-audits) + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory-repo-audits', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact (repo-audits) uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1113,6 +1119,18 @@ jobs: with: name: cache-memory-repo-audits path: /tmp/gh-aw/cache-memory-repo-audits + - name: Validate cache-memory file types (repo-audits) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory-repo-audits', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (repo-audits) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index 46c318a5b8..6a541b22a5 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -510,28 +510,8 @@ jobs: GH_AW_PROMPT_EOF cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" + cat "/opt/gh-aw/prompts/cache_memory_prompt_multi.md" >> "$GH_AW_PROMPT" cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - --- - - ## Cache Folders Available - - You have access to persistent cache folders where you can read and write files to create memories and store information: - - - **focus-areas**: `/tmp/gh-aw/cache-memory-focus-areas/` - - - **Read/Write Access**: You can freely read from and write to any files in these folders - - **Persistence**: Files in these folders persist across workflow runs via GitHub Actions cache - - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved - - **File Share**: Use these as simple file shares - organize files as you see fit - - Examples of what you can store: - - `/tmp/gh-aw/cache-memory-focus-areas/notes.txt` - general notes and observations - - `/tmp/gh-aw/cache-memory-focus-areas/preferences.json` - user preferences and settings - - `/tmp/gh-aw/cache-memory-focus-areas/state/` - organized state files in subdirectories - - Feel free to create, read, update, and organize files in these folders as needed for your tasks. - GitHub API Access Instructions @@ -592,6 +572,16 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' + GH_AW_CACHE_EXAMPLES: '- `/tmp/gh-aw/cache-memory-focus-areas/notes.txt` - general notes and observations +- `/tmp/gh-aw/cache-memory-focus-areas/notes.md` - markdown formatted notes +- `/tmp/gh-aw/cache-memory-focus-areas/preferences.json` - user preferences and settings +- `/tmp/gh-aw/cache-memory-focus-areas/history.jsonl` - activity history in JSON Lines format +- `/tmp/gh-aw/cache-memory-focus-areas/data.csv` - tabular data +- `/tmp/gh-aw/cache-memory-focus-areas/state/` - organized state files in subdirectories (with allowed file types) +' + GH_AW_CACHE_LIST: '- **focus-areas**: `/tmp/gh-aw/cache-memory-focus-areas/` +' GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} @@ -608,6 +598,9 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, + GH_AW_CACHE_EXAMPLES: process.env.GH_AW_CACHE_EXAMPLES, + GH_AW_CACHE_LIST: process.env.GH_AW_CACHE_LIST, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, @@ -778,6 +771,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types (focus-areas) + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory-focus-areas', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact (focus-areas) uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1111,6 +1117,18 @@ jobs: with: name: cache-memory-focus-areas path: /tmp/gh-aw/cache-memory-focus-areas + - name: Validate cache-memory file types (focus-areas) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory-focus-areas', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (focus-areas) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml index 3fd7d5f410..ed938546ef 100644 --- a/.github/workflows/safe-output-health.lock.yml +++ b/.github/workflows/safe-output-health.lock.yml @@ -645,6 +645,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -663,6 +664,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -898,6 +900,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1246,6 +1261,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml index 096470fbe7..642afb3484 100644 --- a/.github/workflows/schema-consistency-checker.lock.yml +++ b/.github/workflows/schema-consistency-checker.lock.yml @@ -569,6 +569,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -587,6 +588,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -807,6 +809,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1155,6 +1170,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 8b80bc3620..bc404a8fb9 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -678,6 +678,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_799BE623: ${{ github.event.issue.number || github.event.pull_request.number }} @@ -700,6 +701,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_799BE623: process.env.GH_AW_EXPR_799BE623, @@ -953,6 +955,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1374,6 +1389,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/security-compliance.lock.yml b/.github/workflows/security-compliance.lock.yml index fa83360bb6..8bb3f96cdb 100644 --- a/.github/workflows/security-compliance.lock.yml +++ b/.github/workflows/security-compliance.lock.yml @@ -542,6 +542,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: memory/campaigns/security-compliance-*/** @@ -550,10 +551,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -909,6 +913,8 @@ jobs: GH_AW_WORKFLOW_ID: "security-compliance" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1066,6 +1072,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1100,6 +1109,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1111,6 +1121,7 @@ jobs: BRANCH_NAME: memory/campaigns MAX_FILE_SIZE: 10240 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "memory/campaigns/security-compliance-*/**" with: script: | diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 9cfcfe772a..7ba8d6f45f 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -729,6 +729,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -749,6 +750,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -926,6 +928,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1321,6 +1336,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/sergo.lock.yml b/.github/workflows/sergo.lock.yml index 8c5bbc697b..7e3834e97a 100644 --- a/.github/workflows/sergo.lock.yml +++ b/.github/workflows/sergo.lock.yml @@ -584,6 +584,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -602,6 +603,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -841,6 +843,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1195,6 +1210,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/slide-deck-maintainer.lock.yml b/.github/workflows/slide-deck-maintainer.lock.yml index 2787170df3..6375972f9a 100644 --- a/.github/workflows/slide-deck-maintainer.lock.yml +++ b/.github/workflows/slide-deck-maintainer.lock.yml @@ -597,6 +597,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -617,6 +618,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -834,6 +836,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1257,6 +1272,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index b9adaffe79..f537eaef5d 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -1386,6 +1386,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -1405,6 +1406,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1664,6 +1666,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -2063,6 +2078,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 22c9e089b3..db0cb743bd 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -950,6 +950,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -968,6 +969,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1132,6 +1134,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1507,6 +1522,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 4c37b1a40e..f1de782af9 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -27,7 +27,7 @@ # - shared/github-queries-safe-input.md # - shared/reporting.md # -# frontmatter-hash: ba8ac38783175d2491cfa23fdbc191b34f88eb3068c3e9b4c795c4c36094a988 +# frontmatter-hash: 23fb974caf81e30df69d8ee71fb9c8a011690ef75670f3f539f699673640002e name: "Smoke Copilot" "on": @@ -1347,6 +1347,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -1366,6 +1367,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1552,6 +1554,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1973,6 +1988,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/smoke-copilot.md b/.github/workflows/smoke-copilot.md index bab2f477a1..33e1dca482 100644 --- a/.github/workflows/smoke-copilot.md +++ b/.github/workflows/smoke-copilot.md @@ -47,9 +47,9 @@ sandbox: container: "ghcr.io/github/gh-aw-mcpg" safe-outputs: add-comment: + allowed-repos: ["github/gh-aw"] hide-older-comments: true max: 2 - allowed-repos: ["github/gh-aw"] create-issue: expires: 2h group: true diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index 437790b710..d442babe57 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -679,6 +679,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_ENV_ORGANIZATION: ${{ env.ORGANIZATION }} @@ -698,6 +699,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_ENV_ORGANIZATION: process.env.GH_AW_ENV_ORGANIZATION, @@ -876,6 +878,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1219,6 +1234,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml index 73fef47549..8e1ba397ed 100644 --- a/.github/workflows/static-analysis-report.lock.yml +++ b/.github/workflows/static-analysis-report.lock.yml @@ -641,6 +641,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -659,6 +660,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -881,6 +883,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1229,6 +1244,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/step-name-alignment.lock.yml b/.github/workflows/step-name-alignment.lock.yml index 66288e1ece..30e9a801e3 100644 --- a/.github/workflows/step-name-alignment.lock.yml +++ b/.github/workflows/step-name-alignment.lock.yml @@ -584,6 +584,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -602,6 +603,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -838,6 +840,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1183,6 +1198,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index 031c185061..4e1d195a12 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -593,6 +593,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -612,6 +613,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -788,6 +790,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1164,6 +1179,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 452787a5e4..333d5f67ad 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -672,6 +672,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -691,6 +692,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -867,6 +869,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1254,6 +1269,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/test-create-pr-error-handling.lock.yml b/.github/workflows/test-create-pr-error-handling.lock.yml index ee075033e7..019ad0695d 100644 --- a/.github/workflows/test-create-pr-error-handling.lock.yml +++ b/.github/workflows/test-create-pr-error-handling.lock.yml @@ -570,6 +570,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -588,6 +589,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -808,6 +810,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1196,6 +1211,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index dcf0d6270c..a2b0597706 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -705,6 +705,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -723,6 +724,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -1008,6 +1010,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1470,6 +1485,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml index e84ab26956..36d858dba0 100644 --- a/.github/workflows/weekly-issue-summary.lock.yml +++ b/.github/workflows/weekly-issue-summary.lock.yml @@ -595,6 +595,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ALLOWED_EXTENSIONS: '.json, .jsonl, .txt, .md, .csv' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -613,6 +614,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, @@ -788,6 +790,19 @@ jobs: # AWF runs with sudo, creating files owned by root sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + - name: Validate cache-memory file types + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Upload cache-memory data as artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: always() @@ -1136,6 +1151,18 @@ jobs: with: name: cache-memory path: /tmp/gh-aw/cache-memory + - name: Validate cache-memory file types (default) + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs'); + const allowedExtensions = [".json",".jsonl",".txt",".md",".csv"]; + const result = validateMemoryFiles('/tmp/gh-aw/cache-memory', 'cache', allowedExtensions); + if (!result.valid) { + core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only .json, .jsonl, .txt, .md, .csv are allowed.`); + } - name: Save cache-memory to cache (default) uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index 3d73f9e172..075da22a3d 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -662,6 +662,7 @@ jobs: - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes - **Merge Strategy**: In case of conflicts, your changes (current version) win - **Persistence**: Files persist across workflow runs via git branch storage + - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation. **Constraints:** - **Allowed Files**: Only files matching patterns: ** @@ -670,10 +671,13 @@ jobs: Examples of what you can store: - `/tmp/gh-aw/repo-memory/default/notes.md` - general notes and observations + - `/tmp/gh-aw/repo-memory/default/notes.txt` - plain text notes - `/tmp/gh-aw/repo-memory/default/state.json` - structured state data - - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories + - `/tmp/gh-aw/repo-memory/default/history.jsonl` - activity history in JSON Lines format + - `/tmp/gh-aw/repo-memory/default/data.csv` - tabular data + - `/tmp/gh-aw/repo-memory/default/history/` - organized history files in subdirectories (with allowed file types) - Feel free to create, read, update, and organize files in this folder as needed for your tasks. + Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. GitHub API Access Instructions @@ -1022,6 +1026,8 @@ jobs: GH_AW_WORKFLOW_ID: "workflow-health-manager" GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }} + GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1211,6 +1217,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }} + validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Checkout actions folder uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -1245,6 +1254,7 @@ jobs: name: repo-memory-default path: /tmp/gh-aw/repo-memory/default - name: Push repo-memory changes (default) + id: push_repo_memory_default if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: @@ -1256,6 +1266,7 @@ jobs: BRANCH_NAME: memory/meta-orchestrators MAX_FILE_SIZE: 102400 MAX_FILE_COUNT: 100 + ALLOWED_EXTENSIONS: '[".json",".jsonl",".txt",".md",".csv"]' FILE_GLOB_FILTER: "**" with: script: | diff --git a/actions/setup/js/handle_agent_failure.cjs b/actions/setup/js/handle_agent_failure.cjs index 9361024157..5b2d3f40a4 100644 --- a/actions/setup/js/handle_agent_failure.cjs +++ b/actions/setup/js/handle_agent_failure.cjs @@ -343,6 +343,20 @@ async function main() { const createDiscussionErrorCount = process.env.GH_AW_CREATE_DISCUSSION_ERROR_COUNT || "0"; const checkoutPRSuccess = process.env.GH_AW_CHECKOUT_PR_SUCCESS || ""; + // Collect repo-memory validation errors from all memory configurations + const repoMemoryValidationErrors = []; + for (const key in process.env) { + if (key.startsWith("GH_AW_REPO_MEMORY_VALIDATION_FAILED_")) { + const memoryID = key.replace("GH_AW_REPO_MEMORY_VALIDATION_FAILED_", ""); + const failed = process.env[key] === "true"; + if (failed) { + const errorKey = `GH_AW_REPO_MEMORY_VALIDATION_ERROR_${memoryID}`; + const errorMessage = process.env[errorKey] || "Unknown validation error"; + repoMemoryValidationErrors.push({ memoryID, errorMessage }); + } + } + } + core.info(`Agent conclusion: ${agentConclusion}`); core.info(`Workflow name: ${workflowName}`); core.info(`Workflow ID: ${workflowID}`); @@ -463,6 +477,16 @@ async function main() { // Build create_discussion errors context const createDiscussionErrorsContext = hasCreateDiscussionErrors ? buildCreateDiscussionErrorsContext(createDiscussionErrors) : ""; + // Build repo-memory validation errors context + let repoMemoryValidationContext = ""; + if (repoMemoryValidationErrors.length > 0) { + repoMemoryValidationContext = "\n**⚠️ Repo-Memory Validation Failed**: Invalid file types detected in repo-memory.\n\n**Validation Errors:**\n"; + for (const { memoryID, errorMessage } of repoMemoryValidationErrors) { + repoMemoryValidationContext += `- Memory "${memoryID}": ${errorMessage}\n`; + } + repoMemoryValidationContext += "\n"; + } + // Build missing_data context const missingDataContext = buildMissingDataContext(); @@ -489,6 +513,7 @@ async function main() { : "", assignment_errors_context: assignmentErrorsContext, create_discussion_errors_context: createDiscussionErrorsContext, + repo_memory_validation_context: repoMemoryValidationContext, missing_data_context: missingDataContext, missing_safe_outputs_context: missingSafeOutputsContext, }; @@ -548,6 +573,16 @@ async function main() { // Build create_discussion errors context const createDiscussionErrorsContext = hasCreateDiscussionErrors ? buildCreateDiscussionErrorsContext(createDiscussionErrors) : ""; + // Build repo-memory validation errors context + let repoMemoryValidationContext = ""; + if (repoMemoryValidationErrors.length > 0) { + repoMemoryValidationContext = "\n**⚠️ Repo-Memory Validation Failed**: Invalid file types detected in repo-memory.\n\n**Validation Errors:**\n"; + for (const { memoryID, errorMessage } of repoMemoryValidationErrors) { + repoMemoryValidationContext += `- Memory "${memoryID}": ${errorMessage}\n`; + } + repoMemoryValidationContext += "\n"; + } + // Build missing_data context const missingDataContext = buildMissingDataContext(); @@ -575,6 +610,7 @@ async function main() { : "", assignment_errors_context: assignmentErrorsContext, create_discussion_errors_context: createDiscussionErrorsContext, + repo_memory_validation_context: repoMemoryValidationContext, missing_data_context: missingDataContext, missing_safe_outputs_context: missingSafeOutputsContext, }; diff --git a/actions/setup/js/push_repo_memory.cjs b/actions/setup/js/push_repo_memory.cjs index 1699f126c8..61417dd6a6 100644 --- a/actions/setup/js/push_repo_memory.cjs +++ b/actions/setup/js/push_repo_memory.cjs @@ -17,6 +17,7 @@ const { execGitSync } = require("./git_helpers.cjs"); * BRANCH_NAME: Branch name to push to * MAX_FILE_SIZE: Maximum file size in bytes * MAX_FILE_COUNT: Maximum number of files per commit + * ALLOWED_EXTENSIONS: JSON array of allowed file extensions (e.g., '[".json",".txt"]') * FILE_GLOB_FILTER: Optional space-separated list of file patterns (e.g., "*.md metrics/** data/**") * Supports * (matches any chars except /) and ** (matches any chars including /) * @@ -43,6 +44,18 @@ async function main() { const maxFileSize = parseInt(process.env.MAX_FILE_SIZE || "10240", 10); const maxFileCount = parseInt(process.env.MAX_FILE_COUNT || "100", 10); const fileGlobFilter = process.env.FILE_GLOB_FILTER || ""; + + // Parse allowed extensions with error handling + let allowedExtensions = [".json", ".jsonl", ".txt", ".md", ".csv"]; + if (process.env.ALLOWED_EXTENSIONS) { + try { + allowedExtensions = JSON.parse(process.env.ALLOWED_EXTENSIONS); + } catch (/** @type {any} */ error) { + core.setFailed(`Failed to parse ALLOWED_EXTENSIONS environment variable: ${error.message}. Expected JSON array format.`); + return; + } + } + const ghToken = process.env.GH_TOKEN; const githubRunId = process.env.GITHUB_RUN_ID || "unknown"; @@ -51,6 +64,7 @@ async function main() { core.info(` MEMORY_ID: ${memoryId}`); core.info(` MAX_FILE_SIZE: ${maxFileSize}`); core.info(` MAX_FILE_COUNT: ${maxFileCount}`); + core.info(` ALLOWED_EXTENSIONS: ${JSON.stringify(allowedExtensions)}`); core.info(` FILE_GLOB_FILTER: ${fileGlobFilter ? `"${fileGlobFilter}"` : "(empty - all files accepted)"}`); core.info(` FILE_GLOB_FILTER length: ${fileGlobFilter.length}`); @@ -241,6 +255,17 @@ async function main() { return; } + // Validate file types before copying + const { validateMemoryFiles } = require("./validate_memory_files.cjs"); + const validation = validateMemoryFiles(sourceMemoryPath, "repo", allowedExtensions); + if (!validation.valid) { + const errorMessage = `File type validation failed: Found ${validation.invalidFiles.length} file(s) with invalid extensions. Only ${allowedExtensions.join(", ")} are allowed. Invalid files: ${validation.invalidFiles.join(", ")}`; + core.setOutput("validation_failed", "true"); + core.setOutput("validation_error", errorMessage); + core.setFailed(errorMessage); + return; + } + core.info(`Copying ${filesToCopy.length} validated file(s)...`); // Copy files to destination (preserving directory structure) diff --git a/actions/setup/js/validate_memory_files.cjs b/actions/setup/js/validate_memory_files.cjs new file mode 100644 index 0000000000..fbfcd3b1ba --- /dev/null +++ b/actions/setup/js/validate_memory_files.cjs @@ -0,0 +1,78 @@ +// @ts-check +/// + +const fs = require("fs"); +const path = require("path"); + +/** + * Validate that all files in a memory directory have allowed file extensions + * Default allowed extensions: .json, .jsonl, .txt, .md, .csv + * + * @param {string} memoryDir - Path to the memory directory to validate + * @param {string} memoryType - Type of memory ("cache" or "repo") for error messages + * @param {string[]} [allowedExtensions] - Optional custom list of allowed extensions (defaults to [".json", ".jsonl", ".txt", ".md", ".csv"]) + * @returns {{valid: boolean, invalidFiles: string[]}} Validation result with list of invalid files + */ +function validateMemoryFiles(memoryDir, memoryType = "cache", allowedExtensions) { + // Use default extensions if not provided or if empty array + const defaultExtensions = [".json", ".jsonl", ".txt", ".md", ".csv"]; + const rawExtensions = allowedExtensions && allowedExtensions.length > 0 ? allowedExtensions : defaultExtensions; + // Normalize extensions to lowercase and trim whitespace + const extensions = rawExtensions.map(ext => ext.trim().toLowerCase()); + const invalidFiles = []; + + // Check if directory exists + if (!fs.existsSync(memoryDir)) { + core.info(`Memory directory does not exist: ${memoryDir}`); + return { valid: true, invalidFiles: [] }; + } + + /** + * Recursively scan directory for files + * @param {string} dirPath - Directory to scan + * @param {string} relativePath - Relative path from memory directory + */ + function scanDirectory(dirPath, relativePath = "") { + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dirPath, entry.name); + const relativeFilePath = relativePath ? path.join(relativePath, entry.name) : entry.name; + + if (entry.isDirectory()) { + // Recursively scan subdirectory + scanDirectory(fullPath, relativeFilePath); + } else if (entry.isFile()) { + // Check file extension + const ext = path.extname(entry.name).toLowerCase(); + if (!extensions.includes(ext)) { + invalidFiles.push(relativeFilePath); + } + } + } + } + + try { + scanDirectory(memoryDir); + } catch (error) { + core.error(`Failed to scan ${memoryType}-memory directory: ${error instanceof Error ? error.message : String(error)}`); + return { valid: false, invalidFiles: [] }; + } + + if (invalidFiles.length > 0) { + core.error(`Found ${invalidFiles.length} file(s) with invalid extensions in ${memoryType}-memory:`); + invalidFiles.forEach(file => { + const ext = path.extname(file).toLowerCase(); + core.error(` - ${file} (extension: ${ext || "(no extension)"})`); + }); + core.error(`Allowed extensions: ${extensions.join(", ")}`); + return { valid: false, invalidFiles }; + } + + core.info(`All files in ${memoryType}-memory directory have valid extensions`); + return { valid: true, invalidFiles: [] }; +} + +module.exports = { + validateMemoryFiles, +}; diff --git a/actions/setup/js/validate_memory_files.test.cjs b/actions/setup/js/validate_memory_files.test.cjs new file mode 100644 index 0000000000..5767a116aa --- /dev/null +++ b/actions/setup/js/validate_memory_files.test.cjs @@ -0,0 +1,202 @@ +// @ts-check + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import fs from "fs"; +import path from "path"; +import os from "os"; + +const { validateMemoryFiles } = require("./validate_memory_files.cjs"); + +// Mock core globally +global.core = { + info: () => {}, + error: () => {}, + warning: () => {}, + debug: () => {}, +}; + +describe("validateMemoryFiles", () => { + let tempDir = ""; + + beforeEach(() => { + // Create a temporary directory for testing + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "validate-memory-test-")); + }); + + afterEach(() => { + // Clean up temporary directory + if (tempDir && fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + + it("returns valid for empty directory", () => { + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("returns valid for non-existent directory", () => { + const nonExistentDir = path.join(tempDir, "does-not-exist"); + const result = validateMemoryFiles(nonExistentDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts .json files", () => { + fs.writeFileSync(path.join(tempDir, "data.json"), '{"test": true}'); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts .jsonl files", () => { + fs.writeFileSync(path.join(tempDir, "data.jsonl"), '{"line": 1}\n{"line": 2}'); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts .txt files", () => { + fs.writeFileSync(path.join(tempDir, "notes.txt"), "Some notes"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts .md files", () => { + fs.writeFileSync(path.join(tempDir, "README.md"), "# Title"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts .csv files", () => { + fs.writeFileSync(path.join(tempDir, "data.csv"), "col1,col2\nval1,val2"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("accepts multiple valid files", () => { + fs.writeFileSync(path.join(tempDir, "data.json"), "{}"); + fs.writeFileSync(path.join(tempDir, "notes.txt"), "notes"); + fs.writeFileSync(path.join(tempDir, "README.md"), "# Title"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("rejects .log files", () => { + fs.writeFileSync(path.join(tempDir, "app.log"), "log entry"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual(["app.log"]); + }); + + it("rejects .yaml files", () => { + fs.writeFileSync(path.join(tempDir, "config.yaml"), "key: value"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual(["config.yaml"]); + }); + + it("rejects .xml files", () => { + fs.writeFileSync(path.join(tempDir, "data.xml"), ""); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual(["data.xml"]); + }); + + it("rejects files without extension", () => { + fs.writeFileSync(path.join(tempDir, "noext"), "content"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual(["noext"]); + }); + + it("rejects multiple invalid files", () => { + fs.writeFileSync(path.join(tempDir, "app.log"), "log"); + fs.writeFileSync(path.join(tempDir, "config.yaml"), "yaml"); + fs.writeFileSync(path.join(tempDir, "valid.json"), "{}"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toHaveLength(2); + expect(result.invalidFiles).toContain("app.log"); + expect(result.invalidFiles).toContain("config.yaml"); + }); + + it("validates files in subdirectories", () => { + const subdir = path.join(tempDir, "subdir"); + fs.mkdirSync(subdir); + fs.writeFileSync(path.join(subdir, "valid.json"), "{}"); + fs.writeFileSync(path.join(subdir, "invalid.log"), "log"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual([path.join("subdir", "invalid.log")]); + }); + + it("validates files in deeply nested directories", () => { + const level1 = path.join(tempDir, "level1"); + const level2 = path.join(level1, "level2"); + const level3 = path.join(level2, "level3"); + fs.mkdirSync(level1); + fs.mkdirSync(level2); + fs.mkdirSync(level3); + fs.writeFileSync(path.join(level3, "deep.json"), "{}"); + fs.writeFileSync(path.join(level3, "invalid.bin"), "binary"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual([path.join("level1", "level2", "level3", "invalid.bin")]); + }); + + it("is case-insensitive for extensions", () => { + fs.writeFileSync(path.join(tempDir, "data.JSON"), "{}"); + fs.writeFileSync(path.join(tempDir, "notes.TXT"), "text"); + fs.writeFileSync(path.join(tempDir, "README.MD"), "# Title"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("handles mixed valid and invalid files in subdirectories", () => { + const subdir1 = path.join(tempDir, "valid-files"); + const subdir2 = path.join(tempDir, "invalid-files"); + fs.mkdirSync(subdir1); + fs.mkdirSync(subdir2); + fs.writeFileSync(path.join(subdir1, "data.json"), "{}"); + fs.writeFileSync(path.join(subdir1, "notes.txt"), "text"); + fs.writeFileSync(path.join(subdir2, "app.log"), "log"); + fs.writeFileSync(path.join(subdir2, "config.ini"), "ini"); + const result = validateMemoryFiles(tempDir, "cache"); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toHaveLength(2); + expect(result.invalidFiles).toContain(path.join("invalid-files", "app.log")); + expect(result.invalidFiles).toContain(path.join("invalid-files", "config.ini")); + }); + + it("accepts custom allowed extensions", () => { + fs.writeFileSync(path.join(tempDir, "config.yaml"), "key: value"); + fs.writeFileSync(path.join(tempDir, "data.xml"), ""); + const customExts = [".yaml", ".xml"]; + const result = validateMemoryFiles(tempDir, "cache", customExts); + expect(result.valid).toBe(true); + expect(result.invalidFiles).toEqual([]); + }); + + it("rejects files not in custom allowed extensions", () => { + fs.writeFileSync(path.join(tempDir, "data.json"), "{}"); + const customExts = [".yaml", ".xml"]; + const result = validateMemoryFiles(tempDir, "cache", customExts); + expect(result.valid).toBe(false); + expect(result.invalidFiles).toEqual(["data.json"]); + }); + + it("uses default extensions when custom array is empty", () => { + fs.writeFileSync(path.join(tempDir, "data.json"), "{}"); + fs.writeFileSync(path.join(tempDir, "notes.txt"), "text"); + const result = validateMemoryFiles(tempDir, "cache", []); + expect(result.valid).toBe(true); // Empty array falls back to defaults + expect(result.invalidFiles).toEqual([]); + }); +}); diff --git a/actions/setup/md/agent_failure_comment.md b/actions/setup/md/agent_failure_comment.md index 7d1089bb6f..93d5c23b54 100644 --- a/actions/setup/md/agent_failure_comment.md +++ b/actions/setup/md/agent_failure_comment.md @@ -1,3 +1,3 @@ Agent job [{run_id}]({run_url}) failed. -{secret_verification_context}{assignment_errors_context}{create_discussion_errors_context}{missing_data_context}{missing_safe_outputs_context} +{secret_verification_context}{assignment_errors_context}{create_discussion_errors_context}{repo_memory_validation_context}{missing_data_context}{missing_safe_outputs_context} diff --git a/actions/setup/md/agent_failure_issue.md b/actions/setup/md/agent_failure_issue.md index 974a957bdc..88a5a84e68 100644 --- a/actions/setup/md/agent_failure_issue.md +++ b/actions/setup/md/agent_failure_issue.md @@ -4,7 +4,7 @@ **Branch:** {branch} **Run URL:** {run_url}{pull_request_info} -{secret_verification_context}{assignment_errors_context}{create_discussion_errors_context}{missing_data_context}{missing_safe_outputs_context} +{secret_verification_context}{assignment_errors_context}{create_discussion_errors_context}{repo_memory_validation_context}{missing_data_context}{missing_safe_outputs_context} ### Action Required diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index dc127ac500..c1414d47af 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -1517,6 +1517,12 @@ tools: # (optional) scope: "workflow" + # List of allowed file extensions (e.g., [".json", ".txt"]). Default: [".json", + # ".jsonl", ".txt", ".md", ".csv"] + # (optional) + allowed-extensions: [] + # Array of strings + # Option 4: Array of cache-memory configurations for multiple caches cache-memory: [] # Array items: object @@ -1714,6 +1720,12 @@ tools: # (optional) create-orphan: true + # List of allowed file extensions (e.g., [".json", ".txt"]). Default: [".json", + # ".jsonl", ".txt", ".md", ".csv"] + # (optional) + allowed-extensions: [] + # Array of strings + # Option 4: Array of repo-memory configurations for multiple memory locations repo-memory: [] # Array items: object diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 47146c8215..4adaafed10 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -824,3 +824,7 @@ var SharedWorkflowForbiddenFields = []string{ func GetWorkflowDir() string { return filepath.Join(".github", "workflows") } + +// DefaultAllowedMemoryExtensions is the default list of allowed file extensions for cache-memory and repo-memory storage. +// These file types are considered safe for AI agent memory storage. +var DefaultAllowedMemoryExtensions = []string{".json", ".jsonl", ".txt", ".md", ".csv"} diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index e7529f1e12..bb674fe47f 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -3127,6 +3127,13 @@ "enum": ["workflow", "repo"], "default": "workflow", "description": "Cache restore key scope: 'workflow' (default, only restores from same workflow) or 'repo' (restores from any workflow in the repository). Use 'repo' with caution as it allows cross-workflow cache sharing." + }, + "allowed-extensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed file extensions (e.g., [\".json\", \".txt\"]). Default: [\".json\", \".jsonl\", \".txt\", \".md\", \".csv\"]" } }, "additionalProperties": false, @@ -3173,6 +3180,13 @@ "enum": ["workflow", "repo"], "default": "workflow", "description": "Cache restore key scope: 'workflow' (default, only restores from same workflow) or 'repo' (restores from any workflow in the repository). Use 'repo' with caution as it allows cross-workflow cache sharing." + }, + "allowed-extensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed file extensions (e.g., [\".json\", \".txt\"]). Default: [\".json\", \".jsonl\", \".txt\", \".md\", \".csv\"]" } }, "required": ["id", "key"], @@ -3459,6 +3473,13 @@ "create-orphan": { "type": "boolean", "description": "Create orphaned branch if it doesn't exist (default: true)" + }, + "allowed-extensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed file extensions (e.g., [\".json\", \".txt\"]). Default: [\".json\", \".jsonl\", \".txt\", \".md\", \".csv\"]" } }, "additionalProperties": false, @@ -3533,6 +3554,13 @@ "create-orphan": { "type": "boolean", "description": "Create orphaned branch if it doesn't exist (default: true)" + }, + "allowed-extensions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of allowed file extensions (e.g., [\".json\", \".txt\"]). Default: [\".json\", \".jsonl\", \".txt\", \".md\", \".csv\"]" } }, "additionalProperties": false diff --git a/pkg/workflow/cache.go b/pkg/workflow/cache.go index d70803547b..2e02097406 100644 --- a/pkg/workflow/cache.go +++ b/pkg/workflow/cache.go @@ -1,10 +1,13 @@ package workflow import ( + "encoding/json" "fmt" "os" + "sort" "strings" + "github.com/github/gh-aw/pkg/constants" "github.com/github/gh-aw/pkg/logger" "github.com/goccy/go-yaml" ) @@ -18,12 +21,13 @@ type CacheMemoryConfig struct { // CacheMemoryEntry represents a single cache-memory configuration type CacheMemoryEntry struct { - ID string `yaml:"id"` // cache identifier (required for array notation) - Key string `yaml:"key,omitempty"` // custom cache key - Description string `yaml:"description,omitempty"` // optional description for this cache - RetentionDays *int `yaml:"retention-days,omitempty"` // retention days for upload-artifact action - RestoreOnly bool `yaml:"restore-only,omitempty"` // if true, only restore cache without saving - Scope string `yaml:"scope,omitempty"` // scope for restore keys: "workflow" (default) or "repo" + ID string `yaml:"id"` // cache identifier (required for array notation) + Key string `yaml:"key,omitempty"` // custom cache key + Description string `yaml:"description,omitempty"` // optional description for this cache + RetentionDays *int `yaml:"retention-days,omitempty"` // retention days for upload-artifact action + RestoreOnly bool `yaml:"restore-only,omitempty"` // if true, only restore cache without saving + Scope string `yaml:"scope,omitempty"` // scope for restore keys: "workflow" (default) or "repo" + AllowedExtensions []string `yaml:"allowed-extensions,omitempty"` // allowed file extensions (default: [".json", ".jsonl", ".txt", ".md", ".csv"]) } // generateDefaultCacheKey generates a default cache key for a given cache ID @@ -34,6 +38,99 @@ func generateDefaultCacheKey(cacheID string) string { return fmt.Sprintf("memory-%s-${{ github.workflow }}-${{ github.run_id }}", cacheID) } +// parseCacheMemoryEntry parses a single cache-memory entry from a map +func parseCacheMemoryEntry(cacheMap map[string]any, defaultID string) (CacheMemoryEntry, error) { + entry := CacheMemoryEntry{ + ID: defaultID, + Key: generateDefaultCacheKey(defaultID), + } + + // Parse ID (for array notation) + if id, exists := cacheMap["id"]; exists { + if idStr, ok := id.(string); ok { + entry.ID = idStr + } + } + // Update key if ID changed + if entry.ID != defaultID { + entry.Key = generateDefaultCacheKey(entry.ID) + } + + // Parse custom key + if key, exists := cacheMap["key"]; exists { + if keyStr, ok := key.(string); ok { + entry.Key = keyStr + // Automatically append -${{ github.run_id }} if the key doesn't already end with it + runIdSuffix := "-${{ github.run_id }}" + if !strings.HasSuffix(entry.Key, runIdSuffix) { + entry.Key = entry.Key + runIdSuffix + } + } + } + + // Parse description + if description, exists := cacheMap["description"]; exists { + if descStr, ok := description.(string); ok { + entry.Description = descStr + } + } + + // Parse retention days + if retentionDays, exists := cacheMap["retention-days"]; exists { + if retentionDaysInt, ok := retentionDays.(int); ok { + entry.RetentionDays = &retentionDaysInt + } else if retentionDaysFloat, ok := retentionDays.(float64); ok { + retentionDaysIntValue := int(retentionDaysFloat) + entry.RetentionDays = &retentionDaysIntValue + } else if retentionDaysUint64, ok := retentionDays.(uint64); ok { + retentionDaysIntValue := int(retentionDaysUint64) + entry.RetentionDays = &retentionDaysIntValue + } + // Validate retention-days bounds + if entry.RetentionDays != nil { + if err := validateIntRange(*entry.RetentionDays, 1, 90, "retention-days"); err != nil { + return entry, err + } + } + } + + // Parse restore-only flag + if restoreOnly, exists := cacheMap["restore-only"]; exists { + if restoreOnlyBool, ok := restoreOnly.(bool); ok { + entry.RestoreOnly = restoreOnlyBool + } + } + + // Parse scope field + if scope, exists := cacheMap["scope"]; exists { + if scopeStr, ok := scope.(string); ok { + entry.Scope = scopeStr + } + } + // Default to "workflow" scope if not specified + if entry.Scope == "" { + entry.Scope = "workflow" + } + + // Parse allowed-extensions field + if allowedExts, exists := cacheMap["allowed-extensions"]; exists { + if extArray, ok := allowedExts.([]any); ok { + entry.AllowedExtensions = make([]string, 0, len(extArray)) + for _, ext := range extArray { + if extStr, ok := ext.(string); ok { + entry.AllowedExtensions = append(entry.AllowedExtensions, extStr) + } + } + } + } + // Default to standard allowed extensions if not specified + if len(entry.AllowedExtensions) == 0 { + entry.AllowedExtensions = constants.DefaultAllowedMemoryExtensions + } + + return entry, nil +} + // extractCacheMemoryConfig extracts cache-memory configuration from tools section // Updated to use ToolsConfig instead of map[string]any func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMemoryConfig, error) { @@ -52,8 +149,9 @@ func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMem if cacheMemoryValue == nil { config.Caches = []CacheMemoryEntry{ { - ID: "default", - Key: generateDefaultCacheKey("default"), + ID: "default", + Key: generateDefaultCacheKey("default"), + AllowedExtensions: constants.DefaultAllowedMemoryExtensions, }, } return config, nil @@ -65,8 +163,9 @@ func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMem // Create a single default cache entry config.Caches = []CacheMemoryEntry{ { - ID: "default", - Key: generateDefaultCacheKey("default"), + ID: "default", + Key: generateDefaultCacheKey("default"), + AllowedExtensions: constants.DefaultAllowedMemoryExtensions, }, } } @@ -80,79 +179,10 @@ func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMem config.Caches = make([]CacheMemoryEntry, 0, len(cacheArray)) for _, item := range cacheArray { if cacheMap, ok := item.(map[string]any); ok { - entry := CacheMemoryEntry{} - - // ID is required for array notation - if id, exists := cacheMap["id"]; exists { - if idStr, ok := id.(string); ok { - entry.ID = idStr - } - } - // Use "default" if no ID specified - if entry.ID == "" { - entry.ID = "default" - } - - // Parse custom key - if key, exists := cacheMap["key"]; exists { - if keyStr, ok := key.(string); ok { - entry.Key = keyStr - // Automatically append -${{ github.run_id }} if the key doesn't already end with it - runIdSuffix := "-${{ github.run_id }}" - if !strings.HasSuffix(entry.Key, runIdSuffix) { - entry.Key = entry.Key + runIdSuffix - } - } - } - // Set default key if not specified - if entry.Key == "" { - entry.Key = generateDefaultCacheKey(entry.ID) - } - - // Parse description - if description, exists := cacheMap["description"]; exists { - if descStr, ok := description.(string); ok { - entry.Description = descStr - } - } - - // Parse retention days - if retentionDays, exists := cacheMap["retention-days"]; exists { - if retentionDaysInt, ok := retentionDays.(int); ok { - entry.RetentionDays = &retentionDaysInt - } else if retentionDaysFloat, ok := retentionDays.(float64); ok { - retentionDaysIntValue := int(retentionDaysFloat) - entry.RetentionDays = &retentionDaysIntValue - } else if retentionDaysUint64, ok := retentionDays.(uint64); ok { - retentionDaysIntValue := int(retentionDaysUint64) - entry.RetentionDays = &retentionDaysIntValue - } - // Validate retention-days bounds - if entry.RetentionDays != nil { - if err := validateIntRange(*entry.RetentionDays, 1, 90, "retention-days"); err != nil { - return nil, err - } - } - } - - // Parse restore-only flag - if restoreOnly, exists := cacheMap["restore-only"]; exists { - if restoreOnlyBool, ok := restoreOnly.(bool); ok { - entry.RestoreOnly = restoreOnlyBool - } - } - - // Parse scope field - if scope, exists := cacheMap["scope"]; exists { - if scopeStr, ok := scope.(string); ok { - entry.Scope = scopeStr - } - } - // Default to "workflow" scope if not specified - if entry.Scope == "" { - entry.Scope = "workflow" + entry, err := parseCacheMemoryEntry(cacheMap, "default") + if err != nil { + return nil, err } - config.Caches = append(config.Caches, entry) } } @@ -168,67 +198,10 @@ func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMem // Handle object configuration (single cache, backward compatible) // Convert to array with single entry if configMap, ok := cacheMemoryValue.(map[string]any); ok { - entry := CacheMemoryEntry{ - ID: "default", - Key: generateDefaultCacheKey("default"), - } - - // Parse custom key - if key, exists := configMap["key"]; exists { - if keyStr, ok := key.(string); ok { - entry.Key = keyStr - // Automatically append -${{ github.run_id }} if the key doesn't already end with it - runIdSuffix := "-${{ github.run_id }}" - if !strings.HasSuffix(entry.Key, runIdSuffix) { - entry.Key = entry.Key + runIdSuffix - } - } - } - - // Parse description - if description, exists := configMap["description"]; exists { - if descStr, ok := description.(string); ok { - entry.Description = descStr - } - } - - // Parse retention days - if retentionDays, exists := configMap["retention-days"]; exists { - if retentionDaysInt, ok := retentionDays.(int); ok { - entry.RetentionDays = &retentionDaysInt - } else if retentionDaysFloat, ok := retentionDays.(float64); ok { - retentionDaysIntValue := int(retentionDaysFloat) - entry.RetentionDays = &retentionDaysIntValue - } else if retentionDaysUint64, ok := retentionDays.(uint64); ok { - retentionDaysIntValue := int(retentionDaysUint64) - entry.RetentionDays = &retentionDaysIntValue - } - // Validate retention-days bounds - if entry.RetentionDays != nil { - if err := validateIntRange(*entry.RetentionDays, 1, 90, "retention-days"); err != nil { - return nil, err - } - } - } - - // Parse restore-only flag - if restoreOnly, exists := configMap["restore-only"]; exists { - if restoreOnlyBool, ok := restoreOnly.(bool); ok { - entry.RestoreOnly = restoreOnlyBool - } - } - - // Parse scope field - if scope, exists := configMap["scope"]; exists { - if scopeStr, ok := scope.(string); ok { - entry.Scope = scopeStr - } - } - // Default to "workflow" scope if not specified - if entry.Scope == "" { - entry.Scope = "workflow" + entry, err := parseCacheMemoryEntry(configMap, "default") + if err != nil { + return nil, err } - config.Caches = []CacheMemoryEntry{entry} return config, nil } @@ -236,6 +209,7 @@ func (c *Compiler) extractCacheMemoryConfig(toolsConfig *ToolsConfig) (*CacheMem return nil, nil } +// extractCacheMemoryConfigFromMap is a backward compatibility wrapper for extractCacheMemoryConfig // extractCacheMemoryConfigFromMap is a backward compatibility wrapper for extractCacheMemoryConfig // that accepts map[string]any instead of *ToolsConfig. This allows gradual migration of calling code. func (c *Compiler) extractCacheMemoryConfigFromMap(tools map[string]any) (*CacheMemoryConfig, error) { @@ -473,6 +447,56 @@ func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData) { } } +// generateCacheMemoryValidation generates validation steps for cache-memory file types +// This should be called after agent execution to validate files before upload/save +func generateCacheMemoryValidation(builder *strings.Builder, data *WorkflowData) { + if data.CacheMemoryConfig == nil || len(data.CacheMemoryConfig.Caches) == 0 { + return + } + + cacheLog.Printf("Generating cache-memory validation steps for %d caches", len(data.CacheMemoryConfig.Caches)) + + // Use backward-compatible paths only when there's a single cache with ID "default" + useBackwardCompatiblePaths := len(data.CacheMemoryConfig.Caches) == 1 && data.CacheMemoryConfig.Caches[0].ID == "default" + + for _, cache := range data.CacheMemoryConfig.Caches { + // Skip restore-only caches + if cache.RestoreOnly { + continue + } + + // Default cache uses /tmp/gh-aw/cache-memory/ for backward compatibility + // Other caches use /tmp/gh-aw/cache-memory-{id}/ to prevent overlaps + var cacheDir string + if cache.ID == "default" { + cacheDir = "/tmp/gh-aw/cache-memory" + } else { + cacheDir = fmt.Sprintf("/tmp/gh-aw/cache-memory-%s", cache.ID) + } + + // Prepare allowed extensions array for JavaScript + allowedExtsJSON, _ := json.Marshal(cache.AllowedExtensions) + + // Build validation script + var validationScript strings.Builder + validationScript.WriteString(" const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');\n") + validationScript.WriteString(" setupGlobals(core, github, context, exec, io);\n") + validationScript.WriteString(" const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs');\n") + fmt.Fprintf(&validationScript, " const allowedExtensions = %s;\n", allowedExtsJSON) + fmt.Fprintf(&validationScript, " const result = validateMemoryFiles('%s', 'cache', allowedExtensions);\n", cacheDir) + validationScript.WriteString(" if (!result.valid) {\n") + fmt.Fprintf(&validationScript, " core.setFailed(`File type validation failed: Found $${result.invalidFiles.length} file(s) with invalid extensions. Only %s are allowed.`);\n", strings.Join(cache.AllowedExtensions, ", ")) + validationScript.WriteString(" }\n") + + // Generate validation step using helper + stepName := "Validate cache-memory file types" + if !useBackwardCompatiblePaths { + stepName = fmt.Sprintf("Validate cache-memory file types (%s)", cache.ID) + } + builder.WriteString(generateInlineGitHubScriptStep(stepName, validationScript.String(), "always()")) + } +} + // generateCacheMemoryArtifactUpload generates artifact upload steps for cache-memory // This should be called after agent execution steps to ensure cache is uploaded after the agent has finished func generateCacheMemoryArtifactUpload(builder *strings.Builder, data *WorkflowData) { @@ -549,30 +573,28 @@ func buildCacheMemoryPromptSection(config *CacheMemoryConfig) *PromptSection { descriptionText = " " + cache.Description } - cacheLog.Printf("Building cache memory prompt section with env vars: cache_dir=%s, description=%s", cacheDir, descriptionText) + // Build allowed extensions text + allowedExtsText := strings.Join(cache.AllowedExtensions, ", ") + + cacheLog.Printf("Building cache memory prompt section with env vars: cache_dir=%s, description=%s, allowed_extensions=%v", cacheDir, descriptionText, cache.AllowedExtensions) // Return prompt section with template file and environment variables for substitution return &PromptSection{ Content: cacheMemoryPromptFile, IsFile: true, EnvVars: map[string]string{ - "GH_AW_CACHE_DIR": cacheDir, - "GH_AW_CACHE_DESCRIPTION": descriptionText, + "GH_AW_CACHE_DIR": cacheDir, + "GH_AW_CACHE_DESCRIPTION": descriptionText, + "GH_AW_ALLOWED_EXTENSIONS": allowedExtsText, }, } } - // Multiple caches or non-default single cache - generate content inline - var content strings.Builder - content.WriteString("\n") - content.WriteString("---\n") - content.WriteString("\n") - content.WriteString("## Cache Folders Available\n") - content.WriteString("\n") - content.WriteString("You have access to persistent cache folders where you can read and write files to create memories and store information:\n") - content.WriteString("\n") + // Multiple caches or non-default single cache - use template file with substitutions + cacheLog.Print("Building cache memory prompt section for multiple caches using template") - // List all caches + // Build cache list + var cacheList strings.Builder for _, cache := range config.Caches { var cacheDir string if cache.ID == "default" { @@ -581,21 +603,51 @@ func buildCacheMemoryPromptSection(config *CacheMemoryConfig) *PromptSection { cacheDir = fmt.Sprintf("/tmp/gh-aw/cache-memory-%s/", cache.ID) } if cache.Description != "" { - fmt.Fprintf(&content, "- **%s**: `%s` - %s\n", cache.ID, cacheDir, cache.Description) + fmt.Fprintf(&cacheList, "- **%s**: `%s` - %s\n", cache.ID, cacheDir, cache.Description) } else { - fmt.Fprintf(&content, "- **%s**: `%s`\n", cache.ID, cacheDir) + fmt.Fprintf(&cacheList, "- **%s**: `%s`\n", cache.ID, cacheDir) } } - content.WriteString("\n") - content.WriteString("- **Read/Write Access**: You can freely read from and write to any files in these folders\n") - content.WriteString("- **Persistence**: Files in these folders persist across workflow runs via GitHub Actions cache\n") - content.WriteString("- **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved\n") - content.WriteString("- **File Share**: Use these as simple file shares - organize files as you see fit\n") - content.WriteString("\n") - content.WriteString("Examples of what you can store:\n") + // Build allowed extensions text + // Check if all caches have the same allowed extensions + allowedExtsText := strings.Join(config.Caches[0].AllowedExtensions, ", ") + allSame := true + for i := 1; i < len(config.Caches); i++ { + if len(config.Caches[i].AllowedExtensions) != len(config.Caches[0].AllowedExtensions) { + allSame = false + break + } + for j, ext := range config.Caches[i].AllowedExtensions { + if ext != config.Caches[0].AllowedExtensions[j] { + allSame = false + break + } + } + if !allSame { + break + } + } - // Add examples for each cache + // If not all the same, build a union of all extensions + if !allSame { + extensionSet := make(map[string]bool) + for _, cache := range config.Caches { + for _, ext := range cache.AllowedExtensions { + extensionSet[ext] = true + } + } + // Convert set to sorted slice for consistent output + var allExtensions []string + for ext := range extensionSet { + allExtensions = append(allExtensions, ext) + } + sort.Strings(allExtensions) + allowedExtsText = strings.Join(allExtensions, ", ") + } + + // Build cache examples + var cacheExamples strings.Builder for _, cache := range config.Caches { var cacheDir string if cache.ID == "default" { @@ -603,17 +655,22 @@ func buildCacheMemoryPromptSection(config *CacheMemoryConfig) *PromptSection { } else { cacheDir = fmt.Sprintf("/tmp/gh-aw/cache-memory-%s", cache.ID) } - fmt.Fprintf(&content, "- `%s/notes.txt` - general notes and observations\n", cacheDir) - fmt.Fprintf(&content, "- `%s/preferences.json` - user preferences and settings\n", cacheDir) - fmt.Fprintf(&content, "- `%s/state/` - organized state files in subdirectories\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/notes.txt` - general notes and observations\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/notes.md` - markdown formatted notes\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/preferences.json` - user preferences and settings\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/history.jsonl` - activity history in JSON Lines format\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/data.csv` - tabular data\n", cacheDir) + fmt.Fprintf(&cacheExamples, "- `%s/state/` - organized state files in subdirectories (with allowed file types)\n", cacheDir) } - content.WriteString("\n") - content.WriteString("Feel free to create, read, update, and organize files in these folders as needed for your tasks.\n") - return &PromptSection{ - Content: content.String(), - IsFile: false, + Content: cacheMemoryPromptMultiFile, + IsFile: true, + EnvVars: map[string]string{ + "GH_AW_CACHE_LIST": cacheList.String(), + "GH_AW_ALLOWED_EXTENSIONS": allowedExtsText, + "GH_AW_CACHE_EXAMPLES": cacheExamples.String(), + }, } } @@ -661,6 +718,24 @@ func (c *Compiler) buildUpdateCacheMemoryJob(data *WorkflowData, threatDetection fmt.Fprintf(&downloadStep, " path: %s\n", cacheDir) steps = append(steps, downloadStep.String()) + // Prepare allowed extensions array for JavaScript + allowedExtsJSON, _ := json.Marshal(cache.AllowedExtensions) + + // Build validation script + var validationScript strings.Builder + validationScript.WriteString(" const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');\n") + validationScript.WriteString(" setupGlobals(core, github, context, exec, io);\n") + validationScript.WriteString(" const { validateMemoryFiles } = require('/opt/gh-aw/actions/validate_memory_files.cjs');\n") + fmt.Fprintf(&validationScript, " const allowedExtensions = %s;\n", allowedExtsJSON) + fmt.Fprintf(&validationScript, " const result = validateMemoryFiles('%s', 'cache', allowedExtensions);\n", cacheDir) + validationScript.WriteString(" if (!result.valid) {\n") + fmt.Fprintf(&validationScript, " core.setFailed(`File type validation failed: Found ${result.invalidFiles.length} file(s) with invalid extensions. Only %s are allowed.`);\n", strings.Join(cache.AllowedExtensions, ", ")) + validationScript.WriteString(" }\n") + + // Generate validation step using helper + stepName := fmt.Sprintf("Validate cache-memory file types (%s)", cache.ID) + steps = append(steps, generateInlineGitHubScriptStep(stepName, validationScript.String(), "")) + // Generate cache key (same logic as in generateCacheMemorySteps) cacheKey := cache.Key if cacheKey == "" { diff --git a/pkg/workflow/cache_memory_import_test.go b/pkg/workflow/cache_memory_import_test.go index e30b3792e1..5d7b1b0f0e 100644 --- a/pkg/workflow/cache_memory_import_test.go +++ b/pkg/workflow/cache_memory_import_test.go @@ -87,7 +87,7 @@ Test cache-memory import without local definition. "- name: Create cache-memory directory (logs)", "path: /tmp/gh-aw/cache-memory-logs", "key: shared-logs-${{ github.run_id }}", - "## Cache Folders Available", + "cache_memory_prompt_multi.md", // Template file reference instead of literal content "- **session**: `/tmp/gh-aw/cache-memory-session/`", "- **logs**: `/tmp/gh-aw/cache-memory-logs/`", } diff --git a/pkg/workflow/cache_memory_integration_test.go b/pkg/workflow/cache_memory_integration_test.go index 7f56b17529..5d315c83a8 100644 --- a/pkg/workflow/cache_memory_integration_test.go +++ b/pkg/workflow/cache_memory_integration_test.go @@ -49,7 +49,7 @@ tools: notExpectedInLock: []string{ // Should NOT upload artifact when detection is disabled "- name: Upload cache-memory data as artifact", - "## Cache Folders Available", + "cache_memory_prompt_multi.md", // Should not use multi template for default-only cache "cache-memory/default/", "cache-memory/session/", }, @@ -85,7 +85,7 @@ tools: "- name: Cache cache-memory file share data (session)", "key: memory-session-${{ github.run_id }}", "path: /tmp/gh-aw/cache-memory-session", - "## Cache Folders Available", + "cache_memory_prompt_multi.md", // Template file reference for multiple caches "- **default**: `/tmp/gh-aw/cache-memory/`", "- **session**: `/tmp/gh-aw/cache-memory-session/`", }, @@ -124,7 +124,7 @@ tools: "mkdir -p /tmp/gh-aw/cache-memory-logs", "key: memory-logs-${{ github.workflow }}-${{ github.run_id }}", "path: /tmp/gh-aw/cache-memory-logs", - "## Cache Folders Available", + "cache_memory_prompt_multi.md", // Template file reference for multiple caches "- **data**: `/tmp/gh-aw/cache-memory-data/`", "- **logs**: `/tmp/gh-aw/cache-memory-logs/`", }, diff --git a/pkg/workflow/cache_memory_prompt_test.go b/pkg/workflow/cache_memory_prompt_test.go index 0f1b92f6b4..c07fee7455 100644 --- a/pkg/workflow/cache_memory_prompt_test.go +++ b/pkg/workflow/cache_memory_prompt_test.go @@ -75,15 +75,24 @@ func TestBuildCacheMemoryPromptSection_MultipleCaches(t *testing.T) { section := buildCacheMemoryPromptSection(config) require.NotNil(t, section, "Should return a prompt section for multiple caches") - assert.False(t, section.IsFile, "Should use inline content for multiple caches") - assert.Contains(t, section.Content, "## Cache Folders Available", "Should have plural header") - assert.Contains(t, section.Content, "- **default**: `/tmp/gh-aw/cache-memory/`", "Should list default cache") - assert.Contains(t, section.Content, "- **session**: `/tmp/gh-aw/cache-memory-session/` - Session-specific cache", "Should list session cache with description") - assert.Contains(t, section.Content, "/tmp/gh-aw/cache-memory/notes.txt", "Should have examples for default cache") - assert.Contains(t, section.Content, "/tmp/gh-aw/cache-memory-session/notes.txt", "Should have examples for session cache") - - // Verify no environment variables for inline content - assert.Empty(t, section.EnvVars, "Inline content should not have environment variables") + assert.True(t, section.IsFile, "Should use template file for multiple caches") + assert.Equal(t, cacheMemoryPromptMultiFile, section.Content, "Should reference template file") + + // Verify environment variables are set + require.NotNil(t, section.EnvVars, "Should have environment variables for template substitution") + assert.Contains(t, section.EnvVars, "GH_AW_CACHE_LIST", "Should have cache list env var") + assert.Contains(t, section.EnvVars, "GH_AW_CACHE_EXAMPLES", "Should have cache examples env var") + assert.Contains(t, section.EnvVars, "GH_AW_ALLOWED_EXTENSIONS", "Should have allowed extensions env var") + + // Verify cache list content + cacheList := section.EnvVars["GH_AW_CACHE_LIST"] + assert.Contains(t, cacheList, "- **default**: `/tmp/gh-aw/cache-memory/`", "Should list default cache") + assert.Contains(t, cacheList, "- **session**: `/tmp/gh-aw/cache-memory-session/` - Session-specific cache", "Should list session cache with description") + + // Verify cache examples content + cacheExamples := section.EnvVars["GH_AW_CACHE_EXAMPLES"] + assert.Contains(t, cacheExamples, "/tmp/gh-aw/cache-memory/notes.txt", "Should have examples for default cache") + assert.Contains(t, cacheExamples, "/tmp/gh-aw/cache-memory-session/notes.txt", "Should have examples for session cache") } func TestBuildCacheMemoryPromptSection_SingleNonDefaultCache(t *testing.T) { @@ -100,10 +109,16 @@ func TestBuildCacheMemoryPromptSection_SingleNonDefaultCache(t *testing.T) { section := buildCacheMemoryPromptSection(config) require.NotNil(t, section, "Should return a prompt section") - assert.False(t, section.IsFile, "Should use inline content for non-default single cache") - assert.Contains(t, section.Content, "## Cache Folders Available", "Should have plural header even for single non-default cache") - assert.Contains(t, section.Content, "- **custom**: `/tmp/gh-aw/cache-memory-custom/` - Custom cache", "Should list custom cache") - assert.Empty(t, section.EnvVars, "Inline content should not have environment variables") + assert.True(t, section.IsFile, "Should use template file for non-default single cache") + assert.Equal(t, "cache_memory_prompt_multi.md", section.Content, "Should reference template file") + + // Verify environment variables + require.NotNil(t, section.EnvVars, "Should have environment variables for template substitution") + assert.Contains(t, section.EnvVars, "GH_AW_CACHE_LIST", "Should have cache list env var") + + // Verify cache list content + cacheList := section.EnvVars["GH_AW_CACHE_LIST"] + assert.Contains(t, cacheList, "- **custom**: `/tmp/gh-aw/cache-memory-custom/` - Custom cache", "Should list custom cache") } func TestBuildCacheMemoryPromptSection_NilConfig(t *testing.T) { @@ -144,15 +159,21 @@ func TestBuildCacheMemoryPromptSection_MultipleCachesWithMixedDescriptions(t *te section := buildCacheMemoryPromptSection(config) require.NotNil(t, section, "Should return a prompt section") - assert.False(t, section.IsFile, "Should use inline content for multiple caches") + assert.True(t, section.IsFile, "Should use template file for multiple caches") + assert.Equal(t, "cache_memory_prompt_multi.md", section.Content, "Should reference template file") - // Verify all caches are listed with correct formatting - assert.Contains(t, section.Content, "- **default**: `/tmp/gh-aw/cache-memory/` - Main cache", "Should list default with description") - assert.Contains(t, section.Content, "- **temp**: `/tmp/gh-aw/cache-memory-temp/`\n", "Should list temp without description") - assert.Contains(t, section.Content, "- **persistent**: `/tmp/gh-aw/cache-memory-persistent/` - Long-term storage", "Should list persistent with description") + // Verify environment variables are set + require.NotNil(t, section.EnvVars, "Should have environment variables") - // Verify examples for all caches - assert.Contains(t, section.Content, "/tmp/gh-aw/cache-memory/notes.txt", "Should have examples for default") - assert.Contains(t, section.Content, "/tmp/gh-aw/cache-memory-temp/notes.txt", "Should have examples for temp") - assert.Contains(t, section.Content, "/tmp/gh-aw/cache-memory-persistent/notes.txt", "Should have examples for persistent") + // Verify all caches are listed in cache list env var + cacheList := section.EnvVars["GH_AW_CACHE_LIST"] + assert.Contains(t, cacheList, "- **default**: `/tmp/gh-aw/cache-memory/` - Main cache", "Should list default with description") + assert.Contains(t, cacheList, "- **temp**: `/tmp/gh-aw/cache-memory-temp/`\n", "Should list temp without description") + assert.Contains(t, cacheList, "- **persistent**: `/tmp/gh-aw/cache-memory-persistent/` - Long-term storage", "Should list persistent with description") + + // Verify examples for all caches in cache examples env var + cacheExamples := section.EnvVars["GH_AW_CACHE_EXAMPLES"] + assert.Contains(t, cacheExamples, "/tmp/gh-aw/cache-memory/notes.txt", "Should have examples for default") + assert.Contains(t, cacheExamples, "/tmp/gh-aw/cache-memory-temp/notes.txt", "Should have examples for temp") + assert.Contains(t, cacheExamples, "/tmp/gh-aw/cache-memory-persistent/notes.txt", "Should have examples for persistent") } diff --git a/pkg/workflow/compiler_yaml_helpers.go b/pkg/workflow/compiler_yaml_helpers.go index 4223bc1d2c..c35f646f5a 100644 --- a/pkg/workflow/compiler_yaml_helpers.go +++ b/pkg/workflow/compiler_yaml_helpers.go @@ -233,6 +233,30 @@ func generateGitHubScriptWithRequire(scriptPath string) string { return script.String() } +// generateInlineGitHubScriptStep generates a simple inline github-script step +// for validation or utility operations that don't require artifact downloads. +// +// Parameters: +// - stepName: The name of the step (e.g., "Validate cache-memory file types") +// - script: The JavaScript code to execute (pre-formatted with proper indentation) +// - condition: Optional if condition (e.g., "always()"). Empty string means no condition. +// +// Returns a string containing the complete YAML for the github-script step. +func generateInlineGitHubScriptStep(stepName, script, condition string) string { + var step strings.Builder + + step.WriteString(" - name: " + stepName + "\n") + if condition != "" { + step.WriteString(" if: " + condition + "\n") + } + step.WriteString(" uses: " + GetActionPin("actions/github-script") + "\n") + step.WriteString(" with:\n") + step.WriteString(" script: |\n") + step.WriteString(script) + + return step.String() +} + // generateSetupStep generates the setup step based on the action mode. // In script mode, it runs the setup.sh script directly from the checked-out source. // In other modes (dev/release), it uses the setup action. diff --git a/pkg/workflow/compiler_yaml_main_job.go b/pkg/workflow/compiler_yaml_main_job.go index 692a1bca7f..5b1b25f73d 100644 --- a/pkg/workflow/compiler_yaml_main_job.go +++ b/pkg/workflow/compiler_yaml_main_job.go @@ -387,6 +387,10 @@ func (c *Compiler) generateMainJobSteps(yaml *strings.Builder, data *WorkflowDat // Add repo-memory artifact upload to save state for push job generateRepoMemoryArtifactUpload(yaml, data) + // Add cache-memory validation (after agent execution) + // This validates file types before cache is saved or uploaded + generateCacheMemoryValidation(yaml, data) + // Add cache-memory artifact upload (after agent execution) // This ensures artifacts are uploaded after the agent has finished modifying the cache generateCacheMemoryArtifactUpload(yaml, data) diff --git a/pkg/workflow/notify_comment.go b/pkg/workflow/notify_comment.go index 83f75c2c76..99faeb77a6 100644 --- a/pkg/workflow/notify_comment.go +++ b/pkg/workflow/notify_comment.go @@ -178,6 +178,16 @@ func (c *Compiler) buildConclusionJob(data *WorkflowData, mainJobName string, sa } } + // Pass repo-memory validation failure outputs if repo-memory is configured + // This allows the agent failure handler to report validation issues + if data.RepoMemoryConfig != nil && len(data.RepoMemoryConfig.Memories) > 0 { + for _, memory := range data.RepoMemoryConfig.Memories { + // Add validation status for each memory + agentFailureEnvVars = append(agentFailureEnvVars, fmt.Sprintf(" GH_AW_REPO_MEMORY_VALIDATION_FAILED_%s: ${{ needs.push_repo_memory.outputs.validation_failed_%s }}\n", memory.ID, memory.ID)) + agentFailureEnvVars = append(agentFailureEnvVars, fmt.Sprintf(" GH_AW_REPO_MEMORY_VALIDATION_ERROR_%s: ${{ needs.push_repo_memory.outputs.validation_error_%s }}\n", memory.ID, memory.ID)) + } + } + // Build the agent failure handling step agentFailureSteps := c.buildGitHubScriptStepWithoutDownload(data, GitHubScriptStepConfig{ StepName: "Handle Agent Failure", diff --git a/pkg/workflow/prompts/cache_memory_prompt.md b/pkg/workflow/prompts/cache_memory_prompt.md index dfaba014dd..a8cb059515 100644 --- a/pkg/workflow/prompts/cache_memory_prompt.md +++ b/pkg/workflow/prompts/cache_memory_prompt.md @@ -8,11 +8,14 @@ You have access to a persistent cache folder at `__CACHE_DIR__` where you can re - **Persistence**: Files in this folder persist across workflow runs via GitHub Actions cache - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved - **File Share**: Use this as a simple file share - organize files as you see fit +- **Allowed File Types**: Only the following file extensions are allowed: `__ALLOWED_EXTENSIONS__`. Files with other extensions will be rejected during validation. Examples of what you can store: - `__CACHE_DIR__notes.txt` - general notes and observations +- `__CACHE_DIR__notes.md` - markdown formatted notes - `__CACHE_DIR__preferences.json` - user preferences and settings -- `__CACHE_DIR__history.log` - activity history and logs -- `__CACHE_DIR__state/` - organized state files in subdirectories +- `__CACHE_DIR__history.jsonl` - activity history in JSON Lines format +- `__CACHE_DIR__data.csv` - tabular data +- `__CACHE_DIR__state/` - organized state files in subdirectories (with allowed file types) -Feel free to create, read, update, and organize files in this folder as needed for your tasks. +Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types. diff --git a/pkg/workflow/prompts/cache_memory_prompt_multi.md b/pkg/workflow/prompts/cache_memory_prompt_multi.md new file mode 100644 index 0000000000..13a69935d8 --- /dev/null +++ b/pkg/workflow/prompts/cache_memory_prompt_multi.md @@ -0,0 +1,20 @@ + +--- + +## Cache Folders Available + +You have access to persistent cache folders where you can read and write files to create memories and store information: + +__CACHE_LIST__ + +- **Read/Write Access**: You can freely read from and write to any files in these folders +- **Persistence**: Files in these folders persist across workflow runs via GitHub Actions cache +- **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved +- **File Share**: Use these as simple file shares - organize files as you see fit +- **Allowed File Types**: Only the following file extensions are allowed: `__ALLOWED_EXTENSIONS__`. Files with other extensions will be rejected during validation. + +Examples of what you can store: + +__CACHE_EXAMPLES__ + +Feel free to create, read, update, and organize files in these folders as needed for your tasks, using only the allowed file types. diff --git a/pkg/workflow/prompts_test.go b/pkg/workflow/prompts_test.go index 27b4d8086c..9509b949be 100644 --- a/pkg/workflow/prompts_test.go +++ b/pkg/workflow/prompts_test.go @@ -305,12 +305,12 @@ This is a test workflow with multiple cache-memory entries. t.Error("Expected 'Create prompt with built-in context' step in generated workflow") } - // Test 2: Verify plural form is used for multiple caches - if !strings.Contains(lockStr, "Cache Folders Available") { - t.Error("Expected 'Cache Folders Available' (plural) header for multiple caches") + // Test 2: Verify multi-cache template file is referenced + if !strings.Contains(lockStr, "cache_memory_prompt_multi.md") { + t.Error("Expected 'cache_memory_prompt_multi.md' template file reference for multiple caches") } - // Test 3: Verify both cache directories are mentioned + // Test 3: Verify both cache directories are mentioned in environment variables if !strings.Contains(lockStr, "/tmp/gh-aw/cache-memory/") { t.Error("Expected '/tmp/gh-aw/cache-memory/' reference for default cache") } diff --git a/pkg/workflow/repo_memory.go b/pkg/workflow/repo_memory.go index 77ed9057ca..ccdb446a62 100644 --- a/pkg/workflow/repo_memory.go +++ b/pkg/workflow/repo_memory.go @@ -18,10 +18,12 @@ package workflow import ( + "encoding/json" "fmt" "regexp" "strings" + "github.com/github/gh-aw/pkg/constants" "github.com/github/gh-aw/pkg/logger" ) @@ -41,14 +43,15 @@ type RepoMemoryConfig struct { // RepoMemoryEntry represents a single repo-memory configuration type RepoMemoryEntry struct { - ID string `yaml:"id"` // memory identifier (required for array notation) - TargetRepo string `yaml:"target-repo,omitempty"` // target repository (default: current repo) - BranchName string `yaml:"branch-name,omitempty"` // branch name (default: memory/{memory-id}) - FileGlob []string `yaml:"file-glob,omitempty"` // file glob patterns for allowed files - MaxFileSize int `yaml:"max-file-size,omitempty"` // maximum size per file in bytes (default: 10KB) - MaxFileCount int `yaml:"max-file-count,omitempty"` // maximum file count per commit (default: 100) - Description string `yaml:"description,omitempty"` // optional description for this memory - CreateOrphan bool `yaml:"create-orphan,omitempty"` // create orphaned branch if missing (default: true) + ID string `yaml:"id"` // memory identifier (required for array notation) + TargetRepo string `yaml:"target-repo,omitempty"` // target repository (default: current repo) + BranchName string `yaml:"branch-name,omitempty"` // branch name (default: memory/{memory-id}) + FileGlob []string `yaml:"file-glob,omitempty"` // file glob patterns for allowed files + MaxFileSize int `yaml:"max-file-size,omitempty"` // maximum size per file in bytes (default: 10KB) + MaxFileCount int `yaml:"max-file-count,omitempty"` // maximum file count per commit (default: 100) + Description string `yaml:"description,omitempty"` // optional description for this memory + CreateOrphan bool `yaml:"create-orphan,omitempty"` // create orphaned branch if missing (default: true) + AllowedExtensions []string `yaml:"allowed-extensions,omitempty"` // allowed file extensions (default: [".json", ".jsonl", ".txt", ".md", ".csv"]) } // RepoMemoryToolConfig represents the configuration for repo-memory in tools @@ -112,11 +115,12 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig) (*RepoMemor repoMemoryLog.Print("Using default repo-memory configuration (nil value)") config.Memories = []RepoMemoryEntry{ { - ID: "default", - BranchName: generateDefaultBranchName("default", config.BranchPrefix), - MaxFileSize: 10240, // 10KB - MaxFileCount: 100, - CreateOrphan: true, + ID: "default", + BranchName: generateDefaultBranchName("default", config.BranchPrefix), + MaxFileSize: 10240, // 10KB + MaxFileCount: 100, + CreateOrphan: true, + AllowedExtensions: constants.DefaultAllowedMemoryExtensions, }, } return config, nil @@ -129,11 +133,12 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig) (*RepoMemor // Create a single default memory entry config.Memories = []RepoMemoryEntry{ { - ID: "default", - BranchName: generateDefaultBranchName("default", config.BranchPrefix), - MaxFileSize: 10240, // 10KB - MaxFileCount: 100, - CreateOrphan: true, + ID: "default", + BranchName: generateDefaultBranchName("default", config.BranchPrefix), + MaxFileSize: 10240, // 10KB + MaxFileCount: 100, + CreateOrphan: true, + AllowedExtensions: constants.DefaultAllowedMemoryExtensions, }, } } else { @@ -260,6 +265,22 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig) (*RepoMemor } } + // Parse allowed-extensions field + if allowedExts, exists := memoryMap["allowed-extensions"]; exists { + if extArray, ok := allowedExts.([]any); ok { + entry.AllowedExtensions = make([]string, 0, len(extArray)) + for _, ext := range extArray { + if extStr, ok := ext.(string); ok { + entry.AllowedExtensions = append(entry.AllowedExtensions, extStr) + } + } + } + } + // Default to standard allowed extensions if not specified + if len(entry.AllowedExtensions) == 0 { + entry.AllowedExtensions = constants.DefaultAllowedMemoryExtensions + } + config.Memories = append(config.Memories, entry) } } @@ -369,6 +390,22 @@ func (c *Compiler) extractRepoMemoryConfig(toolsConfig *ToolsConfig) (*RepoMemor } } + // Parse allowed-extensions field + if allowedExts, exists := configMap["allowed-extensions"]; exists { + if extArray, ok := allowedExts.([]any); ok { + entry.AllowedExtensions = make([]string, 0, len(extArray)) + for _, ext := range extArray { + if extStr, ok := ext.(string); ok { + entry.AllowedExtensions = append(entry.AllowedExtensions, extStr) + } + } + } + } + // Default to standard allowed extensions if not specified + if len(entry.AllowedExtensions) == 0 { + entry.AllowedExtensions = constants.DefaultAllowedMemoryExtensions + } + config.Memories = []RepoMemoryEntry{entry} return config, nil } @@ -601,6 +638,7 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna // Build step with github-script action var step strings.Builder fmt.Fprintf(&step, " - name: Push repo-memory changes (%s)\n", memory.ID) + fmt.Fprintf(&step, " id: push_repo_memory_%s\n", memory.ID) step.WriteString(" if: always()\n") fmt.Fprintf(&step, " uses: %s\n", GetActionPin("actions/github-script")) step.WriteString(" env:\n") @@ -612,6 +650,9 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna fmt.Fprintf(&step, " BRANCH_NAME: %s\n", memory.BranchName) fmt.Fprintf(&step, " MAX_FILE_SIZE: %d\n", memory.MaxFileSize) fmt.Fprintf(&step, " MAX_FILE_COUNT: %d\n", memory.MaxFileCount) + // Pass allowed extensions as JSON array + allowedExtsJSON, _ := json.Marshal(memory.AllowedExtensions) + fmt.Fprintf(&step, " ALLOWED_EXTENSIONS: '%s'\n", allowedExtsJSON) if fileGlobFilter != "" { // Quote the value to prevent YAML alias interpretation of patterns like *.md fmt.Fprintf(&step, " FILE_GLOB_FILTER: \"%s\"\n", fileGlobFilter) @@ -647,6 +688,15 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna jobCondition = "always() && needs.detection.outputs.success == 'true'" } + // Build outputs map for validation failures from all memory steps + outputs := make(map[string]string) + for _, memory := range data.RepoMemoryConfig.Memories { + stepID := fmt.Sprintf("push_repo_memory_%s", memory.ID) + // Add outputs for each memory's validation status + outputs[fmt.Sprintf("validation_failed_%s", memory.ID)] = fmt.Sprintf("${{ steps.%s.outputs.validation_failed }}", stepID) + outputs[fmt.Sprintf("validation_error_%s", memory.ID)] = fmt.Sprintf("${{ steps.%s.outputs.validation_error }}", stepID) + } + job := &Job{ Name: "push_repo_memory", DisplayName: "", // No display name - job ID is sufficient @@ -655,6 +705,7 @@ func (c *Compiler) buildPushRepoMemoryJob(data *WorkflowData, threatDetectionEna Permissions: "permissions:\n contents: write", Needs: []string{"agent"}, // Detection dependency added by caller if needed Steps: steps, + Outputs: outputs, } return job, nil diff --git a/pkg/workflow/repo_memory_prompt.go b/pkg/workflow/repo_memory_prompt.go index 9d09c679d9..ff4d5385fa 100644 --- a/pkg/workflow/repo_memory_prompt.go +++ b/pkg/workflow/repo_memory_prompt.go @@ -2,6 +2,7 @@ package workflow import ( "fmt" + "sort" "strings" "github.com/github/gh-aw/pkg/logger" @@ -44,6 +45,7 @@ func generateRepoMemoryPromptSection(yaml *strings.Builder, config *RepoMemoryCo yaml.WriteString(" - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes\n") yaml.WriteString(" - **Merge Strategy**: In case of conflicts, your changes (current version) win\n") yaml.WriteString(" - **Persistence**: Files persist across workflow runs via git branch storage\n") + yaml.WriteString(" - **Allowed File Types**: Only the following file extensions are allowed: `.json`, `.jsonl`, `.txt`, `.md`, `.csv`. Files with other extensions will be rejected during validation.\n") // Add file constraints if specified if len(memory.FileGlob) > 0 || memory.MaxFileSize > 0 || memory.MaxFileCount > 0 { @@ -63,10 +65,13 @@ func generateRepoMemoryPromptSection(yaml *strings.Builder, config *RepoMemoryCo yaml.WriteString(" \n") yaml.WriteString(" Examples of what you can store:\n") fmt.Fprintf(yaml, " - `%snotes.md` - general notes and observations\n", memoryDir) + fmt.Fprintf(yaml, " - `%snotes.txt` - plain text notes\n", memoryDir) fmt.Fprintf(yaml, " - `%sstate.json` - structured state data\n", memoryDir) - fmt.Fprintf(yaml, " - `%shistory/` - organized history files in subdirectories\n", memoryDir) + fmt.Fprintf(yaml, " - `%shistory.jsonl` - activity history in JSON Lines format\n", memoryDir) + fmt.Fprintf(yaml, " - `%sdata.csv` - tabular data\n", memoryDir) + fmt.Fprintf(yaml, " - `%shistory/` - organized history files in subdirectories (with allowed file types)\n", memoryDir) yaml.WriteString(" \n") - yaml.WriteString(" Feel free to create, read, update, and organize files in this folder as needed for your tasks.\n") + yaml.WriteString(" Feel free to create, read, update, and organize files in this folder as needed for your tasks, using only the allowed file types.\n") } else { // Multiple memories or non-default single memory repoMemoryPromptLog.Printf("Generating multiple repo memory prompts: count=%d", len(config.Memories)) @@ -92,13 +97,52 @@ func generateRepoMemoryPromptSection(yaml *strings.Builder, config *RepoMemoryCo yaml.WriteString(" - **Automatic Push**: Changes are automatically committed and pushed after the workflow completes\n") yaml.WriteString(" - **Merge Strategy**: In case of conflicts, your changes (current version) win\n") yaml.WriteString(" - **Persistence**: Files persist across workflow runs via git branch storage\n") + // Build allowed extensions text - check if all memories have the same extensions + allowedExtsText := strings.Join(config.Memories[0].AllowedExtensions, "`, `") + allSame := true + for i := 1; i < len(config.Memories); i++ { + if len(config.Memories[i].AllowedExtensions) != len(config.Memories[0].AllowedExtensions) { + allSame = false + break + } + for j, ext := range config.Memories[i].AllowedExtensions { + if ext != config.Memories[0].AllowedExtensions[j] { + allSame = false + break + } + } + if !allSame { + break + } + } + + // If not all the same, build a union of all extensions + if !allSame { + extensionSet := make(map[string]bool) + for _, mem := range config.Memories { + for _, ext := range mem.AllowedExtensions { + extensionSet[ext] = true + } + } + // Convert set to sorted slice for consistent output + var allExtensions []string + for ext := range extensionSet { + allExtensions = append(allExtensions, ext) + } + sort.Strings(allExtensions) + allowedExtsText = strings.Join(allExtensions, "`, `") + } + fmt.Fprintf(yaml, " - **Allowed File Types**: Only the following file extensions are allowed: `%s`. Files with other extensions will be rejected during validation.\n", allowedExtsText) yaml.WriteString(" \n") yaml.WriteString(" Examples of what you can store:\n") memoryDir := "/tmp/gh-aw/repo-memory" fmt.Fprintf(yaml, " - `%s/notes.md` - general notes and observations\n", memoryDir) + fmt.Fprintf(yaml, " - `%s/notes.txt` - plain text notes\n", memoryDir) fmt.Fprintf(yaml, " - `%s/state.json` - structured state data\n", memoryDir) - fmt.Fprintf(yaml, " - `%s/history/` - organized history files\n", memoryDir) + fmt.Fprintf(yaml, " - `%s/history.jsonl` - activity history in JSON Lines format\n", memoryDir) + fmt.Fprintf(yaml, " - `%s/data.csv` - tabular data\n", memoryDir) + fmt.Fprintf(yaml, " - `%s/history/` - organized history files (with allowed file types)\n", memoryDir) yaml.WriteString(" \n") - yaml.WriteString(" Feel free to create, read, update, and organize files in these folders as needed for your tasks.\n") + yaml.WriteString(" Feel free to create, read, update, and organize files in these folders as needed for your tasks, using only the allowed file types.\n") } }