mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-17 13:52:14 +01:00
# Description of Changes This pull request updates several GitHub Actions and related dependencies across multiple workflow files to newer versions. The main goal is to keep the CI/CD pipeline up-to-date with the latest security patches, features, and bug fixes provided by upstream maintainers. The changes primarily involve upgrading the versions of commonly used actions like `actions/checkout`, `docker/login-action`, `actions/setup-java`, `gradle/actions/setup-gradle`, and `actions/upload-artifact`. The most important changes are: **Actions Version Upgrades (General Maintenance & Security):** * Upgraded `actions/checkout` from v6.0.1 to v6.0.2 in all workflow files to ensure the latest bug fixes and improvements are used. [[1]](diffhunk://#diff-931fcb06ba030420d7044dde06465ad55b4e769a9bd374dcd6a0c76f79a5e30eL119-R119) [[2]](diffhunk://#diff-931fcb06ba030420d7044dde06465ad55b4e769a9bd374dcd6a0c76f79a5e30eL175-R175) [[3]](diffhunk://#diff-931fcb06ba030420d7044dde06465ad55b4e769a9bd374dcd6a0c76f79a5e30eL365-R365) [[4]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L48-R48) [[5]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L136-R136) [[6]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L148-R160) [[7]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L378-R378) [[8]](diffhunk://#diff-26fc40a450703e6602af586a24594196fb10e132de14a9a488ae64ee8cc51166L29-R29) [[9]](diffhunk://#diff-f1e8b4497f902b85c1b990cd7e6ebd928afd9051757fcb8f376be66260c9ea05L26-R26) [[10]](diffhunk://#diff-cfe84f4bb9657c721ff741644ee0bce45aa81aaef9dea1ea8741c946984e9722L23-R23) [[11]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L39-R39) [[12]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L63-R72) [[13]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L138-R147) [[14]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L175-R177) [[15]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L210-R219) [[16]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L264-R273) [[17]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L328-R328) [[18]](diffhunk://#diff-3117b4a93711d37b0a9a1668272eec716fea0b4f57dde16a85e7ab3f569c455dL35-R35) [[19]](diffhunk://#diff-7cdd3ccec44c8ba176bdc3b9ef54c3f56aa210a1a4e2bb5f79d87b1e50314a18L25-R25) [[20]](diffhunk://#diff-f8b6ec3c0af9cd2d8dffef6f3def2be6357fe596a606850ca7f5d799e1349069L26-R26) [[21]](diffhunk://#diff-3c0f521958c53ad27c967692b4d5480ead136acb33622ee97d39df814b1b202eL33-R33) * Upgraded `docker/login-action` from v3.6.0 to v3.7.0 for improved Docker Hub authentication. [[1]](diffhunk://#diff-931fcb06ba030420d7044dde06465ad55b4e769a9bd374dcd6a0c76f79a5e30eL192-R192) [[2]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L182-R182) [[3]](diffhunk://#diff-f8b6ec3c0af9cd2d8dffef6f3def2be6357fe596a606850ca7f5d799e1349069L88-R88) **Java and Gradle Tooling Updates:** * Updated `actions/setup-java` from v5.0.0 to v5.2.0 and `gradle/actions/setup-gradle` from v5.0.0 to v5.0.1 to get the latest Java and Gradle setup improvements. [[1]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L148-R160) [[2]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L63-R72) [[3]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L138-R147) [[4]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L210-R219) [[5]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L264-R273) [[6]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L338-R344) * Upgraded `actions/setup-node` from v5.0.0 to v6.1.0 for Node.js setup. **Artifact Handling Improvements:** * Upgraded `actions/upload-artifact` from v4.6.2 to v6.0.0 for uploading build and test artifacts, which may include performance and reliability improvements. [[1]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L104-R104) [[2]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L160-R160) [[3]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L193-R193) [[4]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L232-R232) [[5]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L379-R379) **Other Action Updates:** * Updated `actions/ai-inference` from v2.0.4 to v2.0.5 in the AI PR title review workflow. These updates help ensure that the CI/CD workflows remain secure, reliable, and compatible with the latest tools and platforms. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
229 lines
8.4 KiB
YAML
229 lines
8.4 KiB
YAML
name: AI - PR Title Review
|
||
|
||
on:
|
||
pull_request:
|
||
types: [opened, edited]
|
||
branches: [main]
|
||
|
||
permissions: # required for secure-repo hardening
|
||
contents: read
|
||
|
||
jobs:
|
||
ai-title-review:
|
||
permissions:
|
||
contents: read
|
||
pull-requests: write
|
||
models: read
|
||
|
||
runs-on: ubuntu-latest
|
||
|
||
steps:
|
||
- name: Harden Runner
|
||
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||
with:
|
||
egress-policy: audit
|
||
|
||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: Configure Git to suppress detached HEAD warning
|
||
run: git config --global advice.detachedHead false
|
||
|
||
- name: Setup GitHub App Bot
|
||
if: github.actor != 'dependabot[bot]'
|
||
id: setup-bot
|
||
uses: ./.github/actions/setup-bot
|
||
continue-on-error: true
|
||
with:
|
||
app-id: ${{ secrets.GH_APP_ID }}
|
||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||
|
||
- name: Check if actor is repo developer
|
||
id: actor
|
||
run: |
|
||
if [[ "${{ github.actor }}" == *"[bot]" ]]; then
|
||
echo "PR opened by a bot – skipping AI title review."
|
||
echo "is_repo_dev=false" >> $GITHUB_OUTPUT
|
||
exit 0
|
||
fi
|
||
if [ ! -f .github/config/repo_devs.json ]; then
|
||
echo "Error: .github/config/repo_devs.json not found" >&2
|
||
exit 1
|
||
fi
|
||
# Validate JSON and extract repo_devs
|
||
REPO_DEVS=$(jq -r '.repo_devs[]' .github/config/repo_devs.json 2>/dev/null || { echo "Error: Invalid JSON in repo_devs.json" >&2; exit 1; })
|
||
# Convert developer list into Bash array
|
||
mapfile -t DEVS_ARRAY <<< "$REPO_DEVS"
|
||
if [[ " ${DEVS_ARRAY[*]} " == *" ${{ github.actor }} "* ]]; then
|
||
echo "is_repo_dev=true" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "is_repo_dev=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Get PR diff
|
||
if: steps.actor.outputs.is_repo_dev == 'true'
|
||
id: get_diff
|
||
run: |
|
||
git fetch origin ${{ github.base_ref }}
|
||
git diff origin/${{ github.base_ref }}...HEAD | head -n 10000 | grep -vP '[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x{202E}\x{200B}]' > pr.diff
|
||
echo "diff<<EOF" >> $GITHUB_OUTPUT
|
||
cat pr.diff >> $GITHUB_OUTPUT
|
||
echo "EOF" >> $GITHUB_OUTPUT
|
||
|
||
- name: Check and sanitize PR title
|
||
if: steps.actor.outputs.is_repo_dev == 'true'
|
||
id: sanitize_pr_title
|
||
env:
|
||
PR_TITLE_RAW: ${{ github.event.pull_request.title }}
|
||
run: |
|
||
# Sanitize PR title: max 72 characters, only printable characters
|
||
PR_TITLE=$(echo "$PR_TITLE_RAW" | tr -d '\n\r' | head -c 72 | sed 's/[^[:print:]]//g')
|
||
if [[ ${#PR_TITLE} -lt 5 ]]; then
|
||
echo "PR title is too short. Must be at least 5 characters." >&2
|
||
fi
|
||
echo "pr_title=$PR_TITLE" >> $GITHUB_OUTPUT
|
||
|
||
- name: AI PR Title Analysis
|
||
if: steps.actor.outputs.is_repo_dev == 'true'
|
||
id: ai-title-analysis
|
||
uses: actions/ai-inference@a6101c89c6feaecc585efdd8d461f18bb7896f20 # v2.0.5
|
||
with:
|
||
model: openai/gpt-4o
|
||
system-prompt-file: ".github/config/system-prompt.txt"
|
||
prompt: |
|
||
Based on the following input data:
|
||
|
||
{
|
||
"diff": "${{ steps.get_diff.outputs.diff }}",
|
||
"pr_title": "${{ steps.sanitize_pr_title.outputs.pr_title }}"
|
||
}
|
||
|
||
Respond ONLY with valid JSON in the format:
|
||
{
|
||
"improved_rating": <0-10>,
|
||
"improved_ai_title_rating": <0-10>,
|
||
"improved_title": "<ai generated title>"
|
||
}
|
||
|
||
- name: Validate and set SCRIPT_OUTPUT
|
||
if: steps.actor.outputs.is_repo_dev == 'true'
|
||
run: |
|
||
cat <<EOF > ai_response.json
|
||
${{ steps.ai-title-analysis.outputs.response }}
|
||
EOF
|
||
|
||
# Validate JSON structure
|
||
jq -e '
|
||
(keys | sort) == ["improved_ai_title_rating", "improved_rating", "improved_title"] and
|
||
(.improved_rating | type == "number" and . >= 0 and . <= 10) and
|
||
(.improved_ai_title_rating | type == "number" and . >= 0 and . <= 10) and
|
||
(.improved_title | type == "string")
|
||
' ai_response.json
|
||
if [ $? -ne 0 ]; then
|
||
echo "Invalid AI response format" >&2
|
||
cat ai_response.json >&2
|
||
exit 1
|
||
fi
|
||
# Parse JSON fields
|
||
IMPROVED_RATING=$(jq -r '.improved_rating' ai_response.json)
|
||
IMPROVED_TITLE=$(jq -r '.improved_title' ai_response.json)
|
||
# Limit comment length to 1000 characters
|
||
COMMENT=$(cat <<EOF
|
||
## 🤖 AI PR Title Suggestion
|
||
|
||
**PR-Title Rating**: $IMPROVED_RATING/10
|
||
|
||
### ⬇️ Suggested Title (copy & paste):
|
||
|
||
\`\`\`
|
||
$IMPROVED_TITLE
|
||
\`\`\`
|
||
|
||
---
|
||
*Generated by GitHub Models AI*
|
||
EOF
|
||
)
|
||
echo "$COMMENT" > /tmp/ai-title-comment.md
|
||
# Log input and output to the GitHub Step Summary
|
||
echo "### 🤖 AI PR Title Analysis" >> $GITHUB_STEP_SUMMARY
|
||
echo "### Input PR Title" >> $GITHUB_STEP_SUMMARY
|
||
echo '```bash' >> $GITHUB_STEP_SUMMARY
|
||
echo "${{ steps.sanitize_pr_title.outputs.pr_title }}" >> $GITHUB_STEP_SUMMARY
|
||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||
echo '### AI Response (raw JSON)' >> $GITHUB_STEP_SUMMARY
|
||
echo '```json' >> $GITHUB_STEP_SUMMARY
|
||
cat ai_response.json >> $GITHUB_STEP_SUMMARY
|
||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||
|
||
- name: Post comment on PR if needed
|
||
if: steps.actor.outputs.is_repo_dev == 'true'
|
||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||
continue-on-error: true
|
||
with:
|
||
github-token: ${{ steps.setup-bot.outputs.token }}
|
||
script: |
|
||
const fs = require('fs');
|
||
const body = fs.readFileSync('/tmp/ai-title-comment.md', 'utf8');
|
||
const { GITHUB_REPOSITORY } = process.env;
|
||
const [owner, repo] = GITHUB_REPOSITORY.split('/');
|
||
const issue_number = context.issue.number;
|
||
|
||
const ratingMatch = body.match(/\*\*PR-Title Rating\*\*: (\d+)\/10/);
|
||
const rating = ratingMatch ? parseInt(ratingMatch[1], 10) : null;
|
||
|
||
const expectedActor = "${{ steps.setup-bot.outputs.app-slug }}[bot]";
|
||
const comments = await github.rest.issues.listComments({ owner, repo, issue_number });
|
||
|
||
const existing = comments.data.find(c =>
|
||
c.user?.login === expectedActor &&
|
||
c.body.includes("## 🤖 AI PR Title Suggestion")
|
||
);
|
||
|
||
if (rating === null) {
|
||
console.log("No rating found in AI response – skipping.");
|
||
return;
|
||
}
|
||
|
||
if (rating <= 5) {
|
||
if (existing) {
|
||
await github.rest.issues.updateComment({
|
||
owner, repo,
|
||
comment_id: existing.id,
|
||
body
|
||
});
|
||
console.log("Updated existing suggestion comment.");
|
||
} else {
|
||
await github.rest.issues.createComment({
|
||
owner, repo, issue_number,
|
||
body
|
||
});
|
||
console.log("Created new suggestion comment.");
|
||
}
|
||
} else {
|
||
const praise = `## 🤖 AI PR Title Suggestion\n\nGreat job! The current PR title is clear and well-structured.\n\n✅ No suggestions needed.\n\n---\n*Generated by GitHub Models AI*`;
|
||
|
||
if (existing) {
|
||
await github.rest.issues.updateComment({
|
||
owner, repo,
|
||
comment_id: existing.id,
|
||
body: praise
|
||
});
|
||
console.log("Replaced suggestion with praise.");
|
||
} else {
|
||
console.log("Rating > 5 and no existing comment – skipping comment.");
|
||
}
|
||
}
|
||
|
||
- name: is not repo dev
|
||
if: steps.actor.outputs.is_repo_dev != 'true'
|
||
run: |
|
||
exit 0 # Skip the AI title review for non-repo developers
|
||
|
||
- name: Clean up
|
||
if: always()
|
||
run: |
|
||
rm -f pr.diff ai_response.json /tmp/ai-title-comment.md
|
||
echo "Cleaned up temporary files."
|
||
continue-on-error: true # Ensure cleanup runs even if previous steps fail
|