Enhance PR deployment workflow and labeling

Updated labeler config to support conventional commit scopes and expanded API label matching. Added a 'pr-deployed' label to labels.yml. Improved PR deployment workflow to use a local setup-bot action, add the 'pr-deployed' label after deployment, and clean up temporary files. Refactored the cleanup workflow to remove the 'pr-deployed' label and deployment comment on PR close, and improved permissions and step conditions.

https://github.com/Stirling-Tools/Stirling-PDF/security/code-scanning/240
This commit is contained in:
Ludy87 2025-06-29 21:57:48 +02:00
parent 11e3ccd19f
commit 74aec1a72d
No known key found for this signature in database
GPG Key ID: 92696155E0220F94
4 changed files with 143 additions and 38 deletions

View File

@ -2,37 +2,37 @@ version: 1
labels: labels:
- label: "Bugfix" - label: "Bugfix"
title: '^fix:.*' title: '^fix(\([^)]*\))?:|^fix:.*'
- label: "enhancement" - label: "enhancement"
title: '^feat:.*' title: '^feat(\([^)]*\))?:|^feat:.*'
- label: "build" - label: "build"
title: '^build:.*' title: '^build(\([^)]*\))?:|^build:.*'
- label: "chore" - label: "chore"
title: '^chore:.*' title: '^chore(\([^)]*\))?:|^chore:.*'
- label: "ci" - label: "ci"
title: '^ci:.*' title: '^ci(\([^)]*\))?:|^ci:.*'
- label: "perf" - label: "perf"
title: '^perf:.*' title: '^perf(\([^)]*\))?:|^perf:.*'
- label: "refactor" - label: "refactor"
title: '^refactor:.*' title: '^refactor(\([^)]*\))?:|^refactor:.*'
- label: "revert" - label: "revert"
title: '^revert:.*' title: '^revert(\([^)]*\))?:|^revert:.*'
- label: "style" - label: "style"
title: '^style:.*' title: '^style(\([^)]*\))?:|^style:.*'
- label: "Documentation" - label: "Documentation"
title: '^docs:.*' title: '^docs(\([^)]*\))?:|^docs:.*'
- label: 'API' - label: 'API'
title: '.*openapi.*' title: '.*openapi.*|.*swagger.*|.*api.*'
- label: 'Translation' - label: 'Translation'
files: files:
@ -81,6 +81,7 @@ labels:
- 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java' - 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
- 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/.*' - 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/.*'
- 'stirling-pdf/src/main/java/stirling/software/SPDF/model/api/.*' - 'stirling-pdf/src/main/java/stirling/software/SPDF/model/api/.*'
- 'stirling-pdf/src/main/java/stirling/software/SPDF/service/ApiDocService.java'
- 'proprietary/src/main/java/stirling/software/proprietary/security/controller/api/.*' - 'proprietary/src/main/java/stirling/software/proprietary/security/controller/api/.*'
- 'scripts/png_to_webp.py' - 'scripts/png_to_webp.py'
- 'split_photos.py' - 'split_photos.py'

3
.github/labels.yml vendored
View File

@ -175,3 +175,6 @@
description: "This PR changes 1000+ lines ignoring generated files." description: "This PR changes 1000+ lines ignoring generated files."
- name: "to research" - name: "to research"
color: "FBCA04" color: "FBCA04"
- name: "pr-deployed"
color: "00FF00"
description: "Pull request has been deployed to a test environment"

View File

@ -6,20 +6,18 @@ on:
permissions: permissions:
contents: read contents: read
issues: write # Required for adding reactions to comments pull-requests: read
pull-requests: read # Required for reading PR information
jobs: jobs:
check-comment: check-comment:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write
pull-requests: read
if: | if: |
github.event.issue.pull_request && github.event.issue.pull_request &&
( (
contains(github.event.comment.body, 'prdeploy') || contains(github.event.comment.body, 'prdeploy') ||
contains(github.event.comment.body, 'deploypr') contains(github.event.comment.body, 'deploypr')
) )
&& &&
( (
@ -46,10 +44,14 @@ jobs:
with: with:
egress-policy: audit egress-policy: audit
# Generate GitHub App token - name: Checkout PR
- name: Generate GitHub App Token uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
id: generate-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 - name: Setup GitHub App Bot
if: github.actor != 'dependabot[bot]'
id: setup-bot
uses: ./.github/actions/setup-bot
continue-on-error: true
with: with:
app-id: ${{ secrets.GH_APP_ID }} app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
@ -122,7 +124,7 @@ jobs:
id: add-eyes-reaction id: add-eyes-reaction
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
github-token: ${{ steps.generate-token.outputs.token }} github-token: ${{ steps.setup-bot.outputs.token }}
script: | script: |
console.log(`Adding eyes reaction to comment ID: ${context.payload.comment.id}`); console.log(`Adding eyes reaction to comment ID: ${context.payload.comment.id}`);
try { try {
@ -144,8 +146,8 @@ jobs:
needs: check-comment needs: check-comment
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: read
issues: write issues: write
pull-requests: write
steps: steps:
- name: Harden Runner - name: Harden Runner
@ -153,9 +155,14 @@ jobs:
with: with:
egress-policy: audit egress-policy: audit
- name: Generate GitHub App Token - name: Checkout PR
id: generate-token uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
- name: Setup GitHub App Bot
if: github.actor != 'dependabot[bot]'
id: setup-bot
uses: ./.github/actions/setup-bot
continue-on-error: true
with: with:
app-id: ${{ secrets.GH_APP_ID }} app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
@ -165,7 +172,7 @@ jobs:
with: with:
repository: ${{ needs.check-comment.outputs.pr_repository }} repository: ${{ needs.check-comment.outputs.pr_repository }}
ref: ${{ needs.check-comment.outputs.pr_ref }} ref: ${{ needs.check-comment.outputs.pr_ref }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ steps.setup-bot.outputs.token }}
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
@ -187,12 +194,6 @@ jobs:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Get version number
id: versionNumber
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: with:
@ -296,7 +297,7 @@ jobs:
if: success() if: success()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
github-token: ${{ steps.generate-token.outputs.token }} github-token: ${{ steps.setup-bot.outputs.token }}
script: | script: |
console.log(`Adding rocket reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`); console.log(`Adding rocket reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`);
try { try {
@ -312,11 +313,26 @@ jobs:
console.error(error); console.error(error);
} }
// add label to PR
const prNumber = ${{ needs.check-comment.outputs.pr_number }};
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['pr-deployed']
});
console.log(`Added 'pr-deployed' label to PR #${prNumber}`);
} catch (error) {
console.error(`Failed to add label to PR: ${error.message}`);
console.error(error);
}
- name: Add failure reaction to comment - name: Add failure reaction to comment
if: failure() if: failure()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
github-token: ${{ steps.generate-token.outputs.token }} github-token: ${{ steps.setup-bot.outputs.token }}
script: | script: |
console.log(`Adding -1 reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`); console.log(`Adding -1 reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`);
try { try {
@ -336,7 +352,7 @@ jobs:
if: success() if: success()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
github-token: ${{ steps.generate-token.outputs.token }} github-token: ${{ steps.setup-bot.outputs.token }}
script: | script: |
const { GITHUB_REPOSITORY } = process.env; const { GITHUB_REPOSITORY } = process.env;
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/'); const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
@ -356,3 +372,11 @@ jobs:
issue_number: prNumber, issue_number: prNumber,
body: commentBody body: commentBody
}); });
- name: Cleanup temporary files
if: always()
run: |
echo "Cleaning up temporary files..."
rm -f ../private.key docker-compose.yml
echo "Cleanup complete."
continue-on-error: true

View File

@ -1,7 +1,7 @@
name: PR Deployment cleanup name: PR Deployment cleanup
on: on:
pull_request: pull_request_target:
types: [opened, synchronize, reopened, closed] types: [opened, synchronize, reopened, closed]
permissions: permissions:
@ -13,11 +13,11 @@ env:
jobs: jobs:
cleanup: cleanup:
if: github.event.action == 'closed'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write
pull-requests: write pull-requests: write
if: github.event.action == 'closed' issues: write
steps: steps:
- name: Harden Runner - name: Harden Runner
@ -25,13 +25,82 @@ jobs:
with: with:
egress-policy: audit egress-policy: audit
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- 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: Remove 'pr-deployed' label if present
id: remove-label-comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.setup-bot.outputs.token }}
script: |
const prNumber = ${{ github.event.pull_request.number }};
const owner = context.repo.owner;
const repo = context.repo.repo;
// Hole alle Labels auf dem PR
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner,
repo,
issue_number: prNumber
});
const hasLabel = labels.some(label => label.name === 'pr-deployed');
if (hasLabel) {
console.log("Label 'pr-deployed' found. Removing...");
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'pr-deployed'
});
} else {
console.log("Label 'pr-deployed' not found. Nothing to do.");
}
// Find existing comment
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number: prNumber
});
const deploymentComment = comments.data.find(c =>
c.body?.includes("## 🚀 PR Test Deployment") &&
c.user?.type === "Bot"
);
if (deploymentComment) {
await github.rest.issues.deleteComment({
owner,
repo,
comment_id: deploymentComment.id
});
console.log(`Deleted deployment comment (ID: ${deploymentComment.id})`);
} else {
console.log("No matching deployment comment found.");
}
core.setOutput('present', hasLabel || deploymentComment ? 'true' : 'false');
- name: Set up SSH - name: Set up SSH
if: steps.remove-label-comment.outputs.present == 'true'
run: | run: |
mkdir -p ~/.ssh/ mkdir -p ~/.ssh/
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key sudo chmod 600 ../private.key
- name: Cleanup PR deployment - name: Cleanup PR deployment
if: steps.remove-label-comment.outputs.present == 'true'
id: cleanup id: cleanup
run: | run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH' ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
@ -57,3 +126,11 @@ jobs:
echo "NO_CLEANUP_NEEDED" echo "NO_CLEANUP_NEEDED"
fi fi
ENDSSH ENDSSH
- name: Cleanup temporary files
if: always()
run: |
echo "Cleaning up temporary files..."
rm -f ../private.key
echo "Cleanup complete."
continue-on-error: true