@@ -0,0 +1,66 @@
|
|||||||
|
name: Renovate
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0/30 * * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
RENOVATE_VERSION: "41.146.8"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
renovate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
|
- name: Renovate Run
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: tcp://dockerproxy:2375
|
||||||
|
RENOVATE_PLATFORM: gitea
|
||||||
|
RENOVATE_ENDPOINT: https://git.trez.wtf/api/v1
|
||||||
|
RENOVATE_TOKEN: ${{ secrets.RENOVATE_BOT_TOKEN }}
|
||||||
|
LOG_LEVEL: ${{ vars.RENOVATE_LOG_LEVEL }}
|
||||||
|
RENOVATE_GITHUB_COM_TOKEN: ${{ secrets.RENOVATE_GITHUB_TOKEN }}
|
||||||
|
RENOVATE_CONFIG_FILE: renovate.json
|
||||||
|
RENOVATE_REPOSITORIES: trez/ultima-ai
|
||||||
|
RENOVATE_HOST_RULES: |
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "Docker Hub authentication",
|
||||||
|
"hostType": "docker",
|
||||||
|
"matchHost": "docker.io",
|
||||||
|
"username": "${{ secrets.DOCKERHUB_USER }}",
|
||||||
|
"password": "${{ secrets.DOCKERHUB_PASSWORD }}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "GitHub Container Registry (GHCR)",
|
||||||
|
"hostType": "docker",
|
||||||
|
"matchHost": "ghcr.io",
|
||||||
|
"username": "${{ secrets.GHCR_USER }}",
|
||||||
|
"password": "${{ secrets.GHCR_LOGIN_TOKEN }}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Self-hosted Gitea Docker Registry",
|
||||||
|
"hostType": "docker",
|
||||||
|
"matchHost": "git.trez.wtf",
|
||||||
|
"username": "${{ secrets.BOT_GITEA_USER }}",
|
||||||
|
"password": "${{ secrets.BOT_GITEA_PASSWORD }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
run: |
|
||||||
|
docker run --rm \
|
||||||
|
-e RENOVATE_PLATFORM \
|
||||||
|
-e RENOVATE_ENDPOINT \
|
||||||
|
-e RENOVATE_TOKEN \
|
||||||
|
-e LOG_LEVEL \
|
||||||
|
-e RENOVATE_GITHUB_COM_TOKEN \
|
||||||
|
-e RENOVATE_CONFIG_FILE \
|
||||||
|
-e RENOVATE_REPOSITORIES \
|
||||||
|
-e RENOVATE_HOST_RULES \
|
||||||
|
--volumes-from ${{ env.JOB_CONTAINER_NAME }} \
|
||||||
|
-w ${GITHUB_WORKSPACE} \
|
||||||
|
renovate/renovate:${{ env.RENOVATE_VERSION }}-full
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Charish Patel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# PR Commenter Diff-Aware Action
|
||||||
|
|
||||||
|
A GitHub Action to automatically post comments to pull requests on **GitHub** or **Gitea**, based on a `git diff`. Supports:
|
||||||
|
|
||||||
|
- Inline comments per changed line
|
||||||
|
- Multiline comment templates
|
||||||
|
- Cross-platform support (GitHub and Gitea)
|
||||||
|
- Diff-aware commenting, automatically detecting added lines
|
||||||
|
- Default comment template with optional overrides
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **GitHub & Gitea support**: Works seamlessly on both platforms.
|
||||||
|
- **Diff-aware**: Parses a `git diff` to determine which lines were added.
|
||||||
|
- **Inline comments**: Comments appear directly on changed lines in PRs.
|
||||||
|
- **Multiline templates**: Supports `{line}` for single line and `{lines}` for all added lines in a file.
|
||||||
|
- **Reusable**: Works as a composite action and can be called from any workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
| Input | Description | Required | Default |
|
||||||
|
|-------|-------------|----------|---------|
|
||||||
|
| `platform` | Target platform: `github` or `gitea` | yes | `github` |
|
||||||
|
| `token` | API token for authentication | yes | - |
|
||||||
|
| `api_url` | Gitea API URL (only required for Gitea, e.g., `https://gitea.example.com/api/v1`) | no | - |
|
||||||
|
| `repo_owner` | Repository owner (user/org) | yes | - |
|
||||||
|
| `repo_name` | Repository name | yes | - |
|
||||||
|
| `pr_index` | PR number (GitHub) or index (Gitea) | yes | - |
|
||||||
|
| `diff` | Git diff to parse (generated via `git diff`) | yes | - |
|
||||||
|
| `comment_template` | Multiline template for comment body. Use `{line}` for a single line and `{lines}` for all added lines in the file | yes | `Auto-comment: changed line -> {line}` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
comment-pr-diff:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
|
- name: Generate git diff
|
||||||
|
id: gitdiff
|
||||||
|
run: |
|
||||||
|
git fetch origin main
|
||||||
|
git diff origin/main > diff.txt
|
||||||
|
|
||||||
|
- name: Post diff-aware comments to GitHub PR
|
||||||
|
uses: ./ # path to this action
|
||||||
|
with:
|
||||||
|
platform: github
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
repo_owner: ${{ github.repository_owner }}
|
||||||
|
repo_name: ${{ github.event.repository.name }}
|
||||||
|
pr_index: ${{ github.event.pull_request.number }}
|
||||||
|
diff: ${{ steps.gitdiff.outputs.diff }}
|
||||||
|
comment_template: |
|
||||||
|
Auto-comment on file:
|
||||||
|
---
|
||||||
|
Changed line: {line}
|
||||||
|
Full added lines in this file:
|
||||||
|
{lines}
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
name: "PR Commenter Diff-Aware"
|
||||||
|
description: "Post comments to changed lines in a PR based on a git diff, for GitHub or Gitea. Supports multiline templates."
|
||||||
|
author: "Trez.One"
|
||||||
|
|
||||||
|
branding:
|
||||||
|
icon: "paperclip"
|
||||||
|
color: "blue"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: pip install requests
|
||||||
|
|
||||||
|
- name: Run PR commenter
|
||||||
|
run: python git-auto-comment.py
|
||||||
|
shell: python
|
||||||
|
env:
|
||||||
|
PLATFORM: ${{ inputs.platform }}
|
||||||
|
TOKEN: ${{ inputs.token }}
|
||||||
|
API_URL: ${{ inputs.api_url }}
|
||||||
|
REPO_OWNER: ${{ inputs.repo_owner }}
|
||||||
|
REPO_NAME: ${{ inputs.repo_name }}
|
||||||
|
PR_INDEX: ${{ inputs.pr_index }}
|
||||||
|
DIFF: ${{ inputs.diff }}
|
||||||
|
COMMENT_TEMPLATE: ${{ inputs.comment_template }}
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
platform:
|
||||||
|
description: "Target platform: github or gitea"
|
||||||
|
required: true
|
||||||
|
default: "github"
|
||||||
|
token:
|
||||||
|
description: "API token for authentication"
|
||||||
|
required: true
|
||||||
|
api_url:
|
||||||
|
description: "Gitea API URL (only required for Gitea, e.g., https://gitea.example.com/api/v1)"
|
||||||
|
required: false
|
||||||
|
repo_owner:
|
||||||
|
description: "Repository owner (user/org)"
|
||||||
|
required: true
|
||||||
|
repo_name:
|
||||||
|
description: "Repository name"
|
||||||
|
required: true
|
||||||
|
pr_index:
|
||||||
|
description: "PR number (GitHub) or index (Gitea)"
|
||||||
|
required: true
|
||||||
|
diff:
|
||||||
|
description: "Git diff to parse, in standard format (generated via git diff)"
|
||||||
|
required: true
|
||||||
|
comment_template:
|
||||||
|
description: |
|
||||||
|
Multiline template for comment body.
|
||||||
|
Use placeholders:
|
||||||
|
- {line} → replaced by single changed line
|
||||||
|
- {lines} → replaced by all added lines in the file
|
||||||
|
required: true
|
||||||
|
default: "Auto-comment: changed line -> {line}"
|
||||||
Executable
+84
@@ -0,0 +1,84 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
platform = os.environ.get("PLATFORM", "github").lower()
|
||||||
|
token = os.environ["TOKEN"]
|
||||||
|
owner = os.environ["REPO_OWNER"]
|
||||||
|
repo = os.environ["REPO_NAME"]
|
||||||
|
pr_index = os.environ["PR_INDEX"]
|
||||||
|
api_url = os.environ.get("API_URL")
|
||||||
|
diff_text = os.environ.get("DIFF")
|
||||||
|
comment_template = os.environ.get("COMMENT_TEMPLATE", "")
|
||||||
|
|
||||||
|
if not diff_text:
|
||||||
|
print("No diff provided", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Parse diff
|
||||||
|
diff_files = {}
|
||||||
|
current_file = None
|
||||||
|
new_line_num = None
|
||||||
|
|
||||||
|
for line in diff_text.splitlines():
|
||||||
|
if line.startswith("+++ b/"):
|
||||||
|
current_file = line[6:].strip()
|
||||||
|
diff_files[current_file] = []
|
||||||
|
new_line_num = 0
|
||||||
|
elif line.startswith("@@"):
|
||||||
|
m = re.match(r"@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", line)
|
||||||
|
if m:
|
||||||
|
new_line_num = int(m.group(1)) - 1
|
||||||
|
elif line.startswith("+") and not line.startswith("+++"):
|
||||||
|
new_line_num += 1
|
||||||
|
content = line[1:]
|
||||||
|
diff_files[current_file].append((new_line_num, content))
|
||||||
|
elif not line.startswith("-"):
|
||||||
|
new_line_num += 1
|
||||||
|
|
||||||
|
# Post comments
|
||||||
|
for file_path, lines in diff_files.items():
|
||||||
|
if not lines:
|
||||||
|
continue
|
||||||
|
all_lines_content = "\n".join([line_content for _, line_content in lines])
|
||||||
|
for line_number, line_content in lines:
|
||||||
|
body = comment_template.replace("{line}", line_content).replace("{lines}", all_lines_content)
|
||||||
|
|
||||||
|
if platform == "github":
|
||||||
|
url = f"https://api.github.com/repos/{owner}/{repo}/issues/{pr_index}/comments"
|
||||||
|
payload = {"body": body}
|
||||||
|
if file_path and line_number:
|
||||||
|
url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_index}/comments"
|
||||||
|
payload.update({
|
||||||
|
"body": body,
|
||||||
|
"path": file_path,
|
||||||
|
"position": line_number
|
||||||
|
})
|
||||||
|
elif platform == "gitea":
|
||||||
|
if not api_url:
|
||||||
|
print("Gitea API URL required", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
url = f"{api_url}/repos/{owner}/{repo}/pulls/{pr_index}/comments"
|
||||||
|
payload = {"body": body}
|
||||||
|
if file_path and line_number:
|
||||||
|
payload.update({
|
||||||
|
"path": file_path,
|
||||||
|
"position": line_number
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
print(f"Unsupported platform: {platform}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"token {token}",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = requests.post(url, headers=headers, json=payload)
|
||||||
|
if resp.status_code in (201, 200):
|
||||||
|
print(f"Comment posted on {file_path}:{line_number}")
|
||||||
|
else:
|
||||||
|
print(f"Failed to post comment on {file_path}:{line_number} ({resp.status_code})", file=sys.stderr)
|
||||||
|
print(resp.text, file=sys.stderr)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": ["local>trez/renovate-config"],
|
||||||
|
"enabledManagers": ["python"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user