diff --git a/.changeset/patch-configurable-memory-file-types.md b/.changeset/patch-configurable-memory-file-types.md new file mode 100644 index 00000000000..7e11d491ceb --- /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 00000000000..f991752b3f0 --- /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 0413dd11113..c369c67363b 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 c886ab40979..5d0e5a0a7e1 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 79afe897c02..9dff4bf1556 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 6482007bdd8..ee0219e390d 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 2aa9112eefa..685d8d220dc 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 7a335a23fd5..b34124be7a2 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 0acd6caacc5..8dcf1276efa 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 a6b2f0ca50e..05e589214e1 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 28056e20727..d10dc0daa17 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 e197541b9b2..b8545ad97e1 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 f02da153fc4..9dabd987672 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 81093ff89f1..3d724403fa3 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 3965e67aa37..cb4bc680029 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 b3a6ce97cec..664abb744fe 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 184fe22c2aa..9ed7be1bcc5 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 988a490c3e5..d7e724a927b 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 242c00b9954..959341d5541 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 053ad05728e..f67068579c2 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 bf02fc26a07..568fd9629b3 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 5ab9d207446..95d5f75b485 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 99b70bdf8dd..d8916b2f477 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 772813a625a..5f2718ea8db 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 4aad51a8778..a9274704974 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 0cabe98c04c..99623d46e19 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 6f645ed519b..1db0cd3edef 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 b22e2f71dc9..ac7813fe681 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 18f2515bb84..5945081dfe3 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 71c971dd34a..10a42568c03 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 6ba826a8f79..87f51649a87 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 17afb0c02d9..422dd815b48 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 b8a3a0e8fab..a502ec97e8b 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 6e2239ed30d..c4608f7082b 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 8bcdc41a2af..7aa848d84b0 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 7a0b782cacc..d9f2d827cfb 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 7906845a036..039e13e5b01 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 72fe80e0113..39bcf516620 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 c3f21d8011c..ca81bd97ce2 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 efdb922f033..b2571129084 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 56c5a6d6c6c..312a1d7899a 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 4b68ebb8151..37846452699 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 74bddd11f79..09cb40bbc79 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 b398939b9f2..9c20f031ea9 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 aca5f08710b..7d902b2b0f1 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 4f61568b990..46c4a01674e 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 209c0769210..b6d6ec54e91 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 6b075a66781..01b063c2f85 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 1d1409b9dce..ef49e198a9f 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 640f03c8f90..6edfee9260b 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 7a5dad7224f..cce2496c080 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 7cc40dd789e..6605482e04c 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 d33be36f3e9..9915af17da7 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 f9c93fa1ac3..85cc36e6a39 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 54cc91a74e0..0f0f3ab3c26 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 98005b6576c..50ed08d561b 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 23d061fdc4b..dfda5643c08 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 46c318a5b82..6a541b22a5f 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 3fd7d5f410b..ed938546ef1 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 096470fbe7f..642afb34844 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 8b80bc3620b..bc404a8fb9b 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 fa83360bb6a..8bb3f96cdb3 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 9cfcfe772ad..7ba8d6f45f5 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 8c5bbc697bc..7e3834e97a5 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 2787170df35..6375972f9a6 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 b9adaffe798..f537eaef5d4 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 22c9e089b39..db0cb743bd4 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 4c37b1a40ec..f1de782af9f 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 bab2f477a15..33e1dca4826 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 437790b710b..d442babe57d 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 73fef475493..8e1ba397ed7 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 66288e1ecee..30e9a801e3d 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 031c185061a..4e1d195a12b 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 452787a5e48..333d5f67adf 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 ee075033e72..019ad0695d8 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 dcf0d6270c1..a2b05977062 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 e84ab269563..36d858dba03 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 3d73f9e172b..075da22a3d8 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 9361024157e..5b2d3f40a4b 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 1699f126c8c..61417dd6a67 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 00000000000..fbfcd3b1ba6 --- /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 00000000000..5767a116aae --- /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 7d1089bb6f6..93d5c23b54c 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 974a957bdce..88a5a84e681 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 dc127ac500c..c1414d47af8 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 47146c82154..4adaafed106 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 e7529f1e127..bb674fe47f9 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 d70803547b3..2e02097406b 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 e30b3792e13..5d7b1b0f0e5 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 7f56b175299..5d315c83a85 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 0f1b92f6b4c..c07fee7455c 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 4223bc1d2c5..c35f646f5ac 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 692a1bca7f0..5b1b25f73d5 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 83f75c2c761..99faeb77a60 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 dfaba014dd5..a8cb0595159 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 00000000000..13a69935d8e --- /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 27b4d8086c0..9509b949be4 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 77ed9057cac..ccdb446a627 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 9d09c679d9d..ff4d5385fa6 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") } }