Add PR validation workflow and docs#1
Conversation
Add script to handle validation failure comments on PRs.
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)❌ Error creating Unit Test PR.
Comment Tip Migrating from UI to YAML configuration.Use the |
|
Note Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
❌ Failed to create PR with unit tests: AGENT_CHAT: Failed to open pull request |
|
Note Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
scripts/validate_pr.py (3)
126-133: Redundant cast after truthiness check.After verifying
base_shaandhead_shaare truthy (non-empty strings fromos.environ.get), thecast(str, ...)calls are unnecessary since the values are already strings.♻️ Simplified code
def main() -> int: base_sha = os.environ.get("BASE_SHA") head_sha = os.environ.get("HEAD_SHA") if not base_sha or not head_sha: _fail("BASE_SHA and HEAD_SHA environment variables are required") - base_sha = cast(str, base_sha) - head_sha = cast(str, head_sha) - changes = _get_changed_files(base_sha, head_sha)The type checker should narrow the type after the
if not base_sha or not head_shaguard. If your type checker doesn't handle this, you can useassert base_sha and head_shainstead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/validate_pr.py` around lines 126 - 133, The code redundantly calls cast(str, ...) for base_sha and head_sha after the truthiness guard in main; remove the unnecessary cast calls and let the variables remain as the str values returned by os.environ.get, or replace the guard with an assert (e.g., assert base_sha and head_sha) if your type checker needs narrowing; update the references to base_sha and head_sha in main accordingly and ensure the existing _fail branch remains unchanged.
176-195: Consider handling symlinks explicitly.
plugin_root.iterdir()will include symlinks, andchild.is_dir()follows symlinks. A malicious submission could include a symlink pointing outside the plugin directory. Consider checkingchild.is_symlink()and rejecting symlinks.🛡️ Proposed fix to reject symlinks
thumbnails: list[Path] = [] for child in plugin_root.iterdir(): + if child.is_symlink(): + _fail( + f"Symbolic links are not allowed in plugin folders: {child.relative_to(REPO_ROOT)}" + ) if child.is_dir(): _fail( f"No subdirectories are allowed inside a plugin folder: {child.relative_to(REPO_ROOT)}" )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/validate_pr.py` around lines 176 - 195, The current loop over plugin_root.iterdir() does not handle symlinks; update the loop that builds thumbnails: list[Path] = [] and iterates over plugin_root.iterdir() to explicitly reject any symlinks by checking child.is_symlink() before other checks and call _fail with a clear message if true; maintain existing behavior for child.is_dir(), file suffix checks using ALLOWED_IMAGE_EXTS and thumbnail name validation against THUMBNAIL_BASENAME, ensuring symlink rejection happens first so no symlink can point outside the plugin folder.
216-221: Use exception chaining for clearer tracebacks.When re-raising as
SystemExitwithin anexceptblock, usefrom eorfrom Noneto clarify the exception chain.♻️ Proposed fix
if __name__ == "__main__": try: raise SystemExit(main()) except ValidationError as e: print(f"Validation failed: {e}") - raise SystemExit(1) + raise SystemExit(1) from None🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/validate_pr.py` around lines 216 - 221, In the __main__ block, change the re-raise inside the except handler to use explicit exception chaining so the traceback is clear: replace "raise SystemExit(1)" in the except ValidationError as e block with "raise SystemExit(1) from e" (keep the initial "raise SystemExit(main())" as-is) so the chain references the original ValidationError.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/validate-plugin-pr.yml:
- Around line 43-47: The workflow uses the non-existent input script-file on
actions/github-script@v7; replace that usage by reading the external script and
passing its contents to the script input. Concretely, remove the script-file:
scripts/comment_validation_failure.js entry and instead load the file content
(e.g., with a prior step that reads scripts/comment_validation_failure.js into
an output) then set script: to that content for the actions/github-script@v7
step (or alternatively inline the JS into the script: block); refer to the
inputs named script and script-file and the action tag actions/github-script@v7
when making the change.
---
Nitpick comments:
In `@scripts/validate_pr.py`:
- Around line 126-133: The code redundantly calls cast(str, ...) for base_sha
and head_sha after the truthiness guard in main; remove the unnecessary cast
calls and let the variables remain as the str values returned by os.environ.get,
or replace the guard with an assert (e.g., assert base_sha and head_sha) if your
type checker needs narrowing; update the references to base_sha and head_sha in
main accordingly and ensure the existing _fail branch remains unchanged.
- Around line 176-195: The current loop over plugin_root.iterdir() does not
handle symlinks; update the loop that builds thumbnails: list[Path] = [] and
iterates over plugin_root.iterdir() to explicitly reject any symlinks by
checking child.is_symlink() before other checks and call _fail with a clear
message if true; maintain existing behavior for child.is_dir(), file suffix
checks using ALLOWED_IMAGE_EXTS and thumbnail name validation against
THUMBNAIL_BASENAME, ensuring symlink rejection happens first so no symlink can
point outside the plugin folder.
- Around line 216-221: In the __main__ block, change the re-raise inside the
except handler to use explicit exception chaining so the traceback is clear:
replace "raise SystemExit(1)" in the except ValidationError as e block with
"raise SystemExit(1) from e" (keep the initial "raise SystemExit(main())" as-is)
so the chain references the original ValidationError.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e9fa233d-1616-4523-9b3d-78edfc6191fc
📒 Files selected for processing (5)
.github/workflows/validate-plugin-pr.ymlTAGS.mdplugins/_example1/plugin.yamlscripts/comment_validation_failure.jsscripts/validate_pr.py
| - name: Comment on PR (validation failure) | ||
| if: ${{ steps.validate.outputs.exit_code != '0' }} | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script-file: scripts/comment_validation_failure.js |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What inputs does actions/github-script@v7 GitHub Action accept?
💡 Result:
The actions/github-script@v7 GitHub Action accepts the following inputs: - script: The body of an asynchronous JavaScript function to execute (required). - github-token: GitHub token for authentication (optional; defaults to GITHUB_TOKEN). - result-encoding: Encoding for the result output (string, json; default string). - retries: Number of retries for the script (default 0). - debug: Enable debug logging (boolean). - user-agent: Custom user agent prefix. - previews: API preview headers (now GraphQL only in v7). These are used in examples throughout the documentation, such as: with: script: | ... result-encoding: string retries: 3 Note that custom inputs like 'foo' are not valid and will cause warnings; use env vars for additional data passed to the script via process.env to avoid injection risks.
Citations:
- 1: https://github.com/actions/github-script
- 2: https://github.com/marketplace/actions/github-script
- 3: https://stackoverflow.com/questions/78379151/how-to-use-the-output-of-github-script-action-in-the-next-step
🏁 Script executed:
# Check if the script file exists
find . -name "comment_validation_failure.js" -type f
# Check for any other uses of script-file in GitHub workflows
rg "script-file" --type yamlRepository: CtxOS/ctx-plugins
Length of output: 100
🏁 Script executed:
head -50 ./scripts/comment_validation_failure.jsRepository: CtxOS/ctx-plugins
Length of output: 1002
Invalid input script-file for actions/github-script@v7.
The script-file input does not exist in actions/github-script@v7. The action only accepts a script input. This will cause the workflow step to fail.
To execute an external script file, read its content and pass it to the script input:
🔧 Proposed fix
- name: Comment on PR (validation failure)
if: ${{ steps.validate.outputs.exit_code != '0' }}
uses: actions/github-script@v7
with:
- script-file: scripts/comment_validation_failure.js
+ script: |
+ const fs = require('fs');
+ const scriptContent = fs.readFileSync('./scripts/comment_validation_failure.js', 'utf8');
+ eval(scriptContent);Or alternatively, move the script logic inline or use a module export approach if preferred.
🧰 Tools
🪛 actionlint (1.7.11)
[error] 45-45: missing input "script" which is required by action "actions/github-script@v7". all required inputs are "script"
(action)
[error] 47-47: input "script-file" is not defined in action "actions/github-script@v7". available inputs are "base-url", "debug", "github-token", "previews", "result-encoding", "retries", "retry-exempt-status-codes", "script", "user-agent"
(action)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/validate-plugin-pr.yml around lines 43 - 47, The workflow
uses the non-existent input script-file on actions/github-script@v7; replace
that usage by reading the external script and passing its contents to the script
input. Concretely, remove the script-file: scripts/comment_validation_failure.js
entry and instead load the file content (e.g., with a prior step that reads
scripts/comment_validation_failure.js into an output) then set script: to that
content for the actions/github-script@v7 step (or alternatively inline the JS
into the script: block); refer to the inputs named script and script-file and
the action tag actions/github-script@v7 when making the change.
|
❌ Failed to create PR with unit tests: AGENT_CHAT: Failed to open pull request |
|
Note Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
Summary by CodeRabbit
New Features
Documentation
Chores