-
Notifications
You must be signed in to change notification settings - Fork 0
feat(automation): transform repo into self-maintaining ecosystem #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| * @NITISH-R-G |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| name: Standard Issue | ||
| description: Report a bug or request a feature | ||
| title: "[Issue]: " | ||
| labels: ["triage"] | ||
| body: | ||
| - type: markdown | ||
| attributes: | ||
| value: | | ||
| Thanks for taking the time to fill out this issue report! | ||
| - type: textarea | ||
| id: description | ||
| attributes: | ||
| label: Description | ||
| description: A clear and concise description of what the issue or feature request is. | ||
| placeholder: Tell us what you see, what you expect to see, or what you'd like to see added. | ||
| validations: | ||
| required: true | ||
| - type: textarea | ||
| id: steps | ||
| attributes: | ||
| label: Steps To Reproduce (if bug) | ||
| description: Steps to reproduce the behavior. | ||
| validations: | ||
| required: false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| python: | ||
| - all: | ||
| - changed-files: | ||
| - any-glob-to-any-file: '**/*.py' | ||
|
|
||
| documentation: | ||
| - all: | ||
| - changed-files: | ||
| - any-glob-to-any-file: '**/*.md' | ||
| - any-glob-to-any-file: 'docs/**/*' | ||
|
|
||
| frontend: | ||
| - all: | ||
| - changed-files: | ||
| - any-glob-to-any-file: 'web/**/*' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| name: "CodeQL Analysis" | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ "main", "master" ] | ||
| pull_request: | ||
| branches: [ "main", "master" ] | ||
| schedule: | ||
| - cron: '0 0 * * 0' # Weekly | ||
|
|
||
| jobs: | ||
| analyze: | ||
| name: Analyze | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| actions: read | ||
| contents: read | ||
| security-events: write | ||
|
|
||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| language: [ 'python', 'javascript' ] | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Initialize CodeQL | ||
| uses: github/codeql-action/init@v3 | ||
| with: | ||
| languages: ${{ matrix.language }} | ||
|
|
||
| - name: Autobuild | ||
| uses: github/codeql-action/autobuild@v3 | ||
|
|
||
| - name: Perform CodeQL Analysis | ||
| uses: github/codeql-action/analyze@v3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| name: Greetings | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened] | ||
| issues: | ||
| types: [opened] | ||
|
|
||
| jobs: | ||
| greeting: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| issues: write | ||
| pull-requests: write | ||
| steps: | ||
| - uses: actions/first-interaction@v1 | ||
| with: | ||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
| issue-message: "Welcome to our repository! Thank you for raising an issue. A maintainer will check it out shortly." | ||
| pr-message: "Welcome to our repository! Thank you for your first pull request. Please make sure all checks pass and `./validate-submission.sh` was successful locally." |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| name: "Pull Request Labeler" | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
|
|
||
| jobs: | ||
| triage: | ||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/labeler@v5 | ||
| with: | ||
| repo-token: "${{ secrets.GITHUB_TOKEN }}" | ||
| sync-labels: true | ||
|
Comment on lines
+13
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/labeler.yml
printf '%s\n' '--- labeler configuration candidates ---'
git ls-files | grep -E '(^|/)(labeler\.yml|labeler\.yaml)$' || true
printf '%s\n' '--- referenced labeler configuration ---'
rg -n -C 4 'any-glob-to-any-file|all:|documentation|docs/\*\*/\*|\*\*/\*\.md|configuration-path' .githubRepository: NITISH-R-G/ev-grid-oracle Length of output: 1812 🌐 Web query:
💡 Result: In actions/labeler v5, the configuration options for changed files, including any-glob-to-any-file, define the logic used to match pull request file changes against specified glob patterns [1][2][3]. The any-glob-to-any-file option follows the semantic rule where at least one of the provided glob patterns must match at least one of the changed files in the pull request [1][3]. The following table summarizes the semantics for all four supported changed-files matching strategies in v5: Strategy | Semantics --- | --- any-glob-to-any-file | At least one glob matches at least one changed file [1][3]. any-glob-to-all-files | At least one glob matches every changed file [1][3]. all-globs-to-any-file | Every glob must match at least one changed file [1][3]. all-globs-to-all-files | Every glob must match every changed file [1][3]. These rules are applied within the context of the top-level any or all configuration keys, which determine how multiple conditions (such as changed-files, base-branch, or head-branch) are combined [1][2][4]. If no top-level key is provided, the configuration defaults to any [1][3]. These combinations were introduced in the v5 major release to provide more flexible and intuitive matching logic [5]. Citations:
Correct the documentation label rule before enabling this workflow.
🧰 Tools🪛 zizmor (1.29.0)[warning] 1-17: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block (excessive-permissions) [error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| name: Deploy GitHub Pages | ||
|
|
||
| on: | ||
| workflow_run: | ||
| workflows: ["Repository Health Dashboard"] | ||
| types: | ||
| - completed | ||
|
|
||
| permissions: | ||
| contents: write | ||
| pages: write | ||
| id-token: write | ||
|
|
||
| jobs: | ||
| deploy: | ||
| runs-on: ubuntu-latest | ||
| if: ${{ github.event.workflow_run.conclusion == 'success' }} | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Download Dashboard Artifact | ||
| uses: dawidd6/action-download-artifact@v3 | ||
| with: | ||
| workflow: health-dashboard.yml | ||
| name: health-dashboard | ||
| path: ./dashboard_output | ||
|
Comment on lines
+17
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: printf '%s\n' '--- .github/workflows/pages.yml ---'
sed -n '1,140p' .github/workflows/pages.yml
printf '%s\n' '--- .github/workflows/health-dashboard.yml ---'
sed -n '1,180p' .github/workflows/health-dashboard.yml
printf '%s\n' '--- action references and permissions ---'
rg -n -C 3 'workflow_run|action-download-artifact|health-dashboard|contents:|deploy-pages|upload-pages-artifact' .github/workflowsRepository: NITISH-R-G/ev-grid-oracle Length of output: 5776 🌐 Web query:
💡 Result: For the Citations:
🌐 Web query:
💡 Result: The GitHub Actions workflow_run event is a powerful trigger that executes in the context of the base repository, meaning it typically has access to repository secrets and write-scoped GITHUB_TOKEN permissions [1][2][3]. Because it triggers upon the completion of another workflow (often one running untrusted code, such as from a fork's pull request), it is a frequent target for security exploits known as artifact poisoning or pwn requests [4][5][6][2]. Security Risks The primary risk arises when a privileged workflow_run job automatically downloads and consumes artifacts produced by an untrusted upstream workflow [4][6][2]. If an attacker can control the contents of those artifacts (e.g., by submitting a malicious pull request), they can execute arbitrary code within the privileged context of the workflow_run job [4][5][7]. This can lead to the exfiltration of repository secrets, unauthorized repository modifications, or the deployment of malicious code to production [1][5][8]. Official Security Guidance GitHub explicitly advises treating artifacts uploaded by other workflows as untrusted data when consumed in a workflow_run context [2][9]. Official recommendations for securing these workflows include: 1. Treat Artifacts as Untrusted: Never execute binaries, scripts, or configuration files from downloaded artifacts without rigorous validation [4][6][3]. Always treat the contents as potentially malicious [2][3]. 2. Use Privilege Separation: Prefer using the workflow_run event to separate privileged operations from untrusted ones [10][2]. The upstream workflow should perform the untrusted work (e.g., building code) and upload results as artifacts, while the downstream workflow_run performs the privileged operations (e.g., commenting on a PR) [10]. 3. Validate and Sanitize: If you must process artifact data, validate its structure, checksums, or signatures before use [1][6]. Use secure file handling practices, such as extracting artifacts into isolated temporary directories (e.g., /tmp) to prevent overwriting critical workspace files [3]. 4. Strict Filtering: Limit the scope of workflow_run triggers by using branches and workflow name filters to prevent them from executing on untrusted inputs [1][3]. Avoid using these triggers when they are not strictly necessary [2]. 5. Audit Chains: Document and periodically review which workflows can trigger others to ensure that secrets or write permissions are not exposed to untrusted code [1]. By implementing these measures, organizations can significantly reduce the risk of privilege escalation through the artifact-consuming chain of workflow_run events [1][10]. Citations:
Block pull-request artifacts from the write-capable deployment job.
🧰 Tools🪛 zizmor (1.29.0)[warning] 19-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) [error] 23-23: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Deploy to GitHub Pages | ||
| uses: peaceiris/actions-gh-pages@v4 | ||
| with: | ||
| github_token: ${{ secrets.GITHUB_TOKEN }} | ||
| publish_dir: ./dashboard_output | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| name: Repository Maintenance | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ "main", "master" ] | ||
| schedule: | ||
| - cron: '0 0 * * *' # Daily at midnight UTC | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| jobs: | ||
| maintenance: | ||
| runs-on: ubuntu-latest | ||
| if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name == github.repository | ||
|
Comment on lines
+12
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Serialize maintenance runs that write to the same branch. Two push or schedule runs can overlap. Both runs can create commits, but the later Add a workflow or job 🧰 Tools🪛 zizmor (1.29.0)[info] 13-13: workflow or action definition without a name (anonymous-definition): this job (anonymous-definition) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Pin all third-party actions to verified immutable commit SHAs. These workflows use mutable action tags, including jobs with write permissions or access to sensitive tokens. Replace every third-party action reference with a verified full commit SHA and retain the release tag in a comment for readability. Also applies to: 📍 Affects 3 files
🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| with: | ||
| fetch-depth: 0 | ||
| ref: ${{ github.head_ref || github.ref }} | ||
| lfs: true | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.10' | ||
|
|
||
| - name: Install uv | ||
| run: pip install uv | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| uv pip install --system -e ".[dev,demo]" | ||
| uv pip install --system cyclonedx-bom | ||
|
|
||
| - name: Generate Knowledge Graph | ||
| run: | | ||
| mkdir -p artifacts | ||
| python tools/generate_knowledge_graph.py || echo "Knowledge graph generation failed, skipping." | ||
|
|
||
| - name: Sync Documentation | ||
| run: | | ||
| mkdir -p docs | ||
| python tools/docs_sync.py || echo "Docs sync failed, skipping." | ||
|
|
||
| - name: Generate Architecture Diagrams | ||
| run: | | ||
| mkdir -p artifacts | ||
| python tools/generate_architecture_diagrams.py || echo "Architecture diagram generation failed, skipping." | ||
|
|
||
| - name: Generate SBOM | ||
| run: | | ||
| mkdir -p artifacts | ||
| cyclonedx-py environment -o artifacts/bom.json || echo "SBOM generation failed, skipping." | ||
|
Comment on lines
+37
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Fail the workflow when metadata generation fails. Each Remove these fallbacks, or stop before the commit step when any required output fails. 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Commit and Push Changes | ||
| run: | | ||
| git config --global user.name 'github-actions[bot]' | ||
| git config --global user.email 'github-actions[bot]@users.noreply.github.com' | ||
| git add -A | ||
| git diff-index --quiet HEAD || git commit -m "chore(maintenance): automated repository updates" | ||
| git push | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||
| name: Close Stale Issues | ||||||
|
|
||||||
| on: | ||||||
| schedule: | ||||||
| - cron: '30 1 * * *' | ||||||
|
|
||||||
| permissions: | ||||||
| issues: write | ||||||
| pull-requests: write | ||||||
|
|
||||||
| jobs: | ||||||
| stale: | ||||||
| runs-on: ubuntu-latest | ||||||
| steps: | ||||||
| - uses: actions/stale@v9 | ||||||
| with: | ||||||
| stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.' | ||||||
| stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 14 days.' | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: The PR message says stale pull requests will be closed after 14 days, but the global Triggers: When a pull request becomes stale. Suggested fix: Set the close period to 14 days or change
Suggested change
|
||||||
| days-before-stale: 30 | ||||||
| days-before-close: 7 | ||||||
|
Comment on lines
+17
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- .github/workflows/stale.yml ---'
cat -n .github/workflows/stale.yml
printf '%s\n' '--- actions/stale references ---'
rg -n -C 3 'actions/stale|days-before-(issue|pr)-(stale|close)|days-before-(stale|close)' .github/workflows .github 2>/dev/null || true
printf '%s\n' '--- actions/stale v9 action.yml ---'
curl -fsSL https://raw.githubusercontent.com/actions/stale/v9/action.yml |
rg -n -C 5 'days-before-(issue|pr)-(stale|close)|days-before-(stale|close)' || trueRepository: NITISH-R-G/ev-grid-oracle Length of output: 4564 Configure separate pull-request stale timings.
🤖 Prompt for AI Agents |
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,3 +31,6 @@ ev_grid_oracle.egg-info/ | |
| .coverage | ||
| dashboard_output/ | ||
| build/ | ||
|
|
||
| .mypy_cache/ | ||
| .ruff_cache/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Contributor Covenant Code of Conduct | ||
|
|
||
| ## Our Pledge | ||
|
|
||
| We as members, contributors, and leaders pledge to make participation in our | ||
| community a harassment-free experience for everyone, regardless of age, body | ||
| size, visible or invisible disability, ethnicity, sex characteristics, gender | ||
| identity and expression, level of experience, education, socio-economic status, | ||
| nationality, personal appearance, race, religion, or sexual identity | ||
| and orientation. | ||
|
|
||
| We pledge to act and interact in ways that contribute to an open, welcoming, | ||
| diverse, inclusive, and healthy community. | ||
|
|
||
| ## Our Standards | ||
|
|
||
| Examples of behavior that contributes to a positive environment for our | ||
| community include: | ||
|
|
||
| * Demonstrating empathy and kindness toward other people | ||
| * Being respectful of differing opinions, viewpoints, and experiences | ||
| * Giving and gracefully accepting constructive feedback | ||
| * Accepting responsibility and apologizing to those affected by our mistakes, | ||
| and learning from the experience | ||
| * Focusing on what is best not just for us as individuals, but for the | ||
| overall community | ||
|
|
||
| Examples of unacceptable behavior include: | ||
|
|
||
| * The use of sexualized language or imagery, and sexual attention or | ||
| advances of any kind | ||
| * Trolling, insulting or derogatory comments, and personal or political attacks | ||
| * Public or private harassment | ||
| * Publishing others' private information, such as a physical or email | ||
| address, without their explicit permission | ||
| * Other conduct which could reasonably be considered inappropriate in a | ||
| professional setting | ||
|
|
||
| ## Enforcement Responsibilities | ||
|
|
||
| Community leaders are responsible for clarifying and enforcing our standards of | ||
| acceptable behavior and will take appropriate and fair corrective action in | ||
| response to any behavior that they deem inappropriate, threatening, offensive, | ||
| or harmful. | ||
|
|
||
| Community leaders have the right and responsibility to remove, edit, or reject | ||
| comments, commits, code, wiki edits, issues, and other contributions that are | ||
| not aligned to this Code of Conduct, and will communicate reasons for moderation | ||
| decisions when appropriate. | ||
|
Comment on lines
+39
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- candidate policy and reporting files ---'
git ls-files | rg '(^|/)(CODE_OF_CONDUCT|SECURITY|CONTRIBUTING|README)([^/]*)?(\.md)?$|report|conduct' | head -80
printf '%s\n' '--- Code of Conduct ---'
cat -n CODE_OF_CONDUCT.md
printf '%s\n' '--- references to reporting or conduct ---'
rg -n -i 'code of conduct|report(ing)?|violation|harass|moderation|maintainer|security@|contact' --glob '*.md' --glob '*.yml' --glob '*.yaml' --glob '*.txt' . | head -160Repository: NITISH-R-G/ev-grid-oracle Length of output: 9631 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- contribution and contact guidance ---'
rg -n -i -C 3 'contribut|contact|email|security|private|issue|discussion|report|conduct' CONTRIBUTING.md README.md .github CODE_OF_CONDUCT.md 2>/dev/null | head -240
printf '%s\n' '--- repository metadata and issue templates ---'
git ls-files '.github/**' | sort
printf '%s\n' '--- tracked email-like or contact links ---'
rg -n -i '[[:alnum:]._%+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}|mailto:|contact us|report a' --glob '!artifacts/**' --glob '!*.json' . || trueRepository: NITISH-R-G/ev-grid-oracle Length of output: 11968 Add a reporting channel to the Code of Conduct. The repository documents no private reporting contact or reporting process. Add a maintainer email or link to reporting instructions. 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Contributing to the Repository | ||
|
|
||
| First off, thank you for considering contributing to this repository. It's people like you that make open source such a great community. | ||
|
|
||
| ## 1. Where do I go from here? | ||
|
|
||
| If you've noticed a bug or have a feature request, make one! It's generally best if you get confirmation of your bug or approval for your feature request this way before starting to code. | ||
|
|
||
| ## 2. Fork & create a branch | ||
|
|
||
| If this is something you think you can fix, then fork and create a branch with a descriptive name. | ||
|
|
||
| ## 3. Implementation Guidelines | ||
|
|
||
| - Strictly follow an Agile Scrum continuous improvement methodology. | ||
| - Maintain strong coding standards (SOLID, DRY). | ||
| - We use `ruff` for linting/formatting and `mypy` for 100% type-safety. | ||
| - Run local validation tools via `./validate-submission.sh`. No code is merged unless it passes formatting, type checking, and test suites. | ||
|
|
||
| ## 4. Make a Pull Request | ||
|
|
||
| At this point, you should switch back to your master branch and make sure it's up to date with the main repository's master branch. | ||
| Then push your feature branch and create a Pull Request. | ||
|
|
||
| Please describe what you did and why, and link to the relevant issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: NITISH-R-G/ev-grid-oracle
Length of output: 5033
🌐 Web query:
GitHub Actions official documentation pull_request fork GITHUB_TOKEN read-only pull_request_target write permissions actions labeler first-interaction💡 Result:
In GitHub Actions, the choice between the pull_request and pull_request_target event triggers is a critical security decision, particularly when managing contributions from forked repositories [1][2][3]. The pull_request event is designed to be safe for untrusted code [1][2]. When a pull request is opened from a fork, GitHub restricts the GITHUB_TOKEN to read-only permissions and withholds access to repository secrets to prevent malicious code in the pull request from compromising the base repository [1][2]. Because of these restrictions, automation tasks that require write permissions—such as applying labels via the Labeler Action or posting welcome comments via the First Interaction Action—will fail if they attempt to modify the repository [4][5]. The pull_request_target event was created to enable necessary repository automation on pull requests from forks [1][2]. Unlike pull_request, workflows triggered by pull_request_target run in the context of the base repository and are granted a GITHUB_TOKEN with write permissions and access to repository secrets [1][2][3]. However, this elevated trust creates a significant security risk often called a "pwn request" [6][3]. If a workflow triggered by pull_request_target checks out and executes code from an untrusted pull request (e.g., using actions/checkout), an attacker can execute malicious code with the workflow's full privileges, potentially exfiltrating secrets or modifying repository contents [6][7][3]. To use these triggers securely: 1. Prefer pull_request whenever possible [1][2][7]. 2. If you must use pull_request_target for tasks like labeling or triage, ensure the workflow never checks out or executes code from the pull request itself [2][7]. 3. Apply the principle of least privilege by explicitly defining the necessary permissions in your workflow's permissions block (e.g., granting only pull-requests: write and issues: write) rather than relying on default settings [1][4][8][5]. 4. Be aware that modern versions of actions/checkout (v7+) now include protections that prevent the checkout of fork pull request code in pull_request_target workflows by default; opting out of this protection requires explicit use of the allow-unsafe-pr-checkout flag, which should be reserved for exceptional cases [6][7].
Citations:
🌐 Web query:
site:docs.github.com actions pull_request fork read-only GITHUB_TOKEN permissions pull_request_target official💡 Result:
In GitHub Actions, the permissions granted to the GITHUB_TOKEN depend on the event that triggers the workflow and whether the pull request originates from a fork [1][2]. For standard pull_request events, GitHub intentionally restricts the GITHUB_TOKEN to read-only permissions [1][2]. This restriction is a security measure designed to protect the base repository, as the workflow is running code sourced from the pull request's merge commit [1]. Furthermore, for pull requests from forks, the GITHUB_TOKEN has no access to repository secrets [1][2]. In contrast, the pull_request_target event is designed to be used when you need elevated trust, such as for labeling or triage automation that requires interacting with the base repository [1]. Because this event triggers a workflow using the version of the workflow file from the base repository's default branch rather than the untrusted pull request commit, it is considered safe to grant the GITHUB_TOKEN read/write repository permissions and access to secrets [1][3]. Repository administrators can further configure these behaviors through settings: - Run workflows from fork pull requests: An organization or repository setting that determines whether workflows triggered by fork pull requests can run at all, and sets the default GITHUB_TOKEN to read-only with no access to secrets [4]. - Send write tokens to workflows from pull requests: A specific setting that may allow pull requests from forks to use a GITHUB_TOKEN with write permissions if enabled [4]. - Permissions key: In any workflow, you can explicitly use the permissions key to define the required scope of the GITHUB_TOKEN, following the principle of least privilege [5][6][3]. This key can be used to override defaults, allowing you to restrict permissions even in elevated contexts like pull_request_target or grant necessary permissions in other scenarios [5][3].
Citations:
🌐 Web query:
site:docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository "Send write tokens to workflows from pull requests"💡 Result:
To enable sending write tokens to workflows triggered by pull requests from forks, you must configure the repository settings in GitHub. This setting is primarily intended to allow fork pull requests to use a GITHUB_TOKEN with write permissions [1]. You can manage this by navigating to your repository's settings and adjusting the GitHub Actions permissions [1]. Specifically, look for the option labeled "Send write tokens to workflows from pull requests" under the Actions settings [1]. Enabling this allows workflows triggered by fork-based pull requests to access a GITHUB_TOKEN with write permissions, which is otherwise restricted to read-only access by default for security reasons [1]. It is important to note that granting write access to fork-based pull requests can introduce security risks, as it allows external contributors to potentially modify repository resources [1]. In addition to this setting, you can further secure your workflows by using the permissions key within your workflow file to explicitly define the scopes of your GITHUB_TOKEN [1]. For sensitive workflows, it is also recommended to use the "Require approval for fork pull request workflows" setting, which ensures that workflow runs from contributors without write access must be reviewed by a collaborator before executing [1].
Citations:
Use a trusted metadata-only trigger for fork pull requests.
Fork
pull_requestruns can receive a read-onlyGITHUB_TOKEN, soactions/labelerandactions/first-interactionmay not complete their write operations. Replacepull_requestwithpull_request_targetin both workflows. Keep both workflows free of fork-code checkout and execution.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 1-17: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[warning] 2-4: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
📍 Affects 2 files
.github/workflows/labeler.yml#L2-L4(this comment).github/workflows/greetings.yml#L3-L7🤖 Prompt for AI Agents