Skip to content

Commit d28ad89

Browse files
authored
gha cleanups (Stirling-Tools#6275)
# Description of Changes Adds all pre commit PR checks under single file with job validator to have a true "required" run step "all-checks-passed" check Moves all GHAs into workflow helper function calls Note if: always() overrides the default skip-on-needs-failure, "Needs" is added to ensure the validation runs at end of all other tasks --- ## 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/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 run `task check` to verify linters, typechecks, and tests pass - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing) for more details.
1 parent d8c1ffa commit d28ad89

15 files changed

Lines changed: 998 additions & 741 deletions

.github/config/.files.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,25 @@ frontend: &frontend
5555
- scripts/type3_to_cff.py
5656
- scripts/update_type3_library.py
5757

58+
# Files that affect the Tauri desktop bundle. Gate the multi-OS Tauri build
59+
# job on changes to any of these.
60+
tauri: &tauri
61+
- frontend/src-tauri/**
62+
- frontend/src/desktop/**
63+
- frontend/tsconfig.desktop.json
64+
- frontend/package.json
65+
- frontend/package-lock.json
66+
- frontend/vite.config.ts
67+
- .github/workflows/tauri-build.yml
68+
69+
# Files that affect the AI engine (Python tool models, fixers, tests). Gate
70+
# the engine validation job on changes to engine sources or to the Java
71+
# tool surfaces it generates models from.
72+
engine: &engine
73+
- engine/**
74+
- app/(common|core|proprietary)/src/main/java/**
75+
- .github/workflows/ai-engine.yml
76+
5877
licenses-frontend: &licenses-frontend
5978
- ".github/workflows/frontend-backend-licenses-update.yml"
6079
- "frontend/package.json"

.github/workflows/ai-engine.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
name: AI Engine CI
22

3+
# Validates the Python AI engine: regenerates tool models, runs fixers,
4+
# lint, type-check, and tests. Called from build.yml on PRs and merge_group;
5+
# also runs directly on push to main as a post-merge safety net.
36
on:
7+
workflow_call:
48
push:
59
branches: [main]
6-
pull_request:
7-
merge_group:
8-
branches: [main]
910

1011
permissions:
1112
contents: read
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
name: Backend build, format check, and coverage
2+
3+
# Reusable workflow called from build.yml. Runs the full backend build matrix
4+
# (JDK 21/25 × spring-security on/off), Spotless formatting check, JUnit, and
5+
# posts Jacoco coverage to PRs.
6+
on:
7+
workflow_call:
8+
9+
permissions:
10+
contents: read
11+
actions: read
12+
security-events: write
13+
pull-requests: write
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
jdk-version: [21, 25]
22+
spring-security: [true, false]
23+
steps:
24+
- name: Harden Runner
25+
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
26+
with:
27+
egress-policy: audit
28+
- name: Checkout repository
29+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
30+
31+
- name: Set up JDK ${{ matrix.jdk-version }}
32+
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
33+
with:
34+
java-version: ${{ matrix.jdk-version }}
35+
distribution: "temurin"
36+
37+
- name: Cache Gradle dependency artifacts
38+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
39+
with:
40+
path: |
41+
~/.gradle/wrapper
42+
~/.gradle/caches/modules-2/files-2.1
43+
~/.gradle/caches/modules-2/metadata-2.*
44+
key: gradle-deps-${{ runner.os }}-jdk-${{ matrix.jdk-version }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
45+
46+
- name: Setup Gradle
47+
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
48+
with:
49+
gradle-version: 9.3.1
50+
cache-disabled: true
51+
52+
- name: Install Task
53+
uses: go-task/setup-task@3be4020d41929789a01026e0e427a4321ce0ad44 # v2.0.0
54+
- name: Check Java formatting (Spotless)
55+
if: matrix.jdk-version == 25 && matrix.spring-security == false
56+
id: spotless-check
57+
run: task backend:format:check
58+
continue-on-error: true
59+
env:
60+
MAVEN_USER: ${{ secrets.MAVEN_USER }}
61+
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
62+
MAVEN_PUBLIC_URL: ${{ secrets.MAVEN_PUBLIC_URL }}
63+
64+
- name: Comment on Java formatting failure
65+
# Only post a comment on PRs. github-script's PR helpers need an
66+
# issue/PR number, which doesn't exist on merge_group runs.
67+
if: steps.spotless-check.outcome == 'failure' && github.event_name == 'pull_request'
68+
continue-on-error: true
69+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
70+
with:
71+
script: |
72+
const marker = '<!-- java-formatting-check -->';
73+
const body = [
74+
marker,
75+
'### Java Formatting Check Failed',
76+
'',
77+
'Your code has formatting issues. Run the following command to fix them:',
78+
'',
79+
'```bash',
80+
'task backend:format',
81+
'```',
82+
'',
83+
'Then commit and push the changes.',
84+
].join('\n');
85+
const { data: comments } = await github.rest.issues.listComments({
86+
owner: context.repo.owner,
87+
repo: context.repo.repo,
88+
issue_number: context.issue.number,
89+
});
90+
const existing = comments.find(c => c.body.includes(marker));
91+
if (existing) {
92+
await github.rest.issues.updateComment({
93+
owner: context.repo.owner,
94+
repo: context.repo.repo,
95+
comment_id: existing.id,
96+
body,
97+
});
98+
} else {
99+
await github.rest.issues.createComment({
100+
owner: context.repo.owner,
101+
repo: context.repo.repo,
102+
issue_number: context.issue.number,
103+
body,
104+
});
105+
}
106+
107+
- name: Fail if Java formatting issues found
108+
if: steps.spotless-check.outcome == 'failure'
109+
run: |
110+
echo "============================================"
111+
echo " Java Formatting Check Failed"
112+
echo "============================================"
113+
echo ""
114+
echo "Your code has formatting issues."
115+
echo "Run the following command to fix them:"
116+
echo ""
117+
echo " task backend:format"
118+
echo ""
119+
echo "Then commit and push the changes."
120+
echo "============================================"
121+
exit 1
122+
123+
- name: Build with Gradle and spring security ${{ matrix.spring-security }}
124+
run: task backend:build:ci
125+
env:
126+
MAVEN_USER: ${{ secrets.MAVEN_USER }}
127+
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
128+
MAVEN_PUBLIC_URL: ${{ secrets.MAVEN_PUBLIC_URL }}
129+
DISABLE_ADDITIONAL_FEATURES: ${{ matrix.spring-security }}
130+
131+
- name: Check Test Reports Exist
132+
if: always()
133+
run: |
134+
declare -a dirs=(
135+
"app/core/build/reports/tests/"
136+
"app/core/build/test-results/"
137+
"app/common/build/reports/tests/"
138+
"app/common/build/test-results/"
139+
"app/proprietary/build/reports/tests/"
140+
"app/proprietary/build/test-results/"
141+
)
142+
for dir in "${dirs[@]}"; do
143+
if [ ! -d "$dir" ]; then
144+
echo "Missing $dir"
145+
exit 1
146+
fi
147+
done
148+
149+
- name: Upload Test Reports
150+
if: always()
151+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
152+
with:
153+
name: test-reports-jdk-${{ matrix.jdk-version }}-spring-security-${{ matrix.spring-security }}
154+
path: |
155+
app/**/build/reports/jacoco/test
156+
app/**/build/reports/tests/
157+
app/**/build/test-results/
158+
app/**/build/reports/problems/
159+
build/reports/problems/
160+
retention-days: 3
161+
if-no-files-found: warn
162+
163+
- name: Add coverage to PR with spring security ${{ matrix.spring-security }} and JDK ${{ matrix.jdk-version }}
164+
# The action only supports the pull_request event (it posts a PR comment),
165+
# so skip it for merge_group runs and workflow_dispatch.
166+
if: github.event_name == 'pull_request'
167+
id: jacoco
168+
uses: madrapps/jacoco-report@50d3aff4548aa991e6753342d9ba291084e63848 # v1.7.2
169+
with:
170+
paths: |
171+
${{ github.workspace }}/**/build/reports/jacoco/test/jacocoTestReport.xml
172+
token: ${{ secrets.GITHUB_TOKEN }}
173+
min-coverage-overall: 10
174+
min-coverage-changed-files: 0
175+
comment-type: summary

.github/workflows/build-enterprise.yml

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ name: Enterprise E2E (Playwright)
66
# situations:
77
#
88
# - PRs that touch proprietary / premium / SSO compose / enterprise tests
9-
# (path-filtered against .github/config/.files.yaml `proprietary`),
9+
# (driven by build.yml via workflow_call, path-filtered against
10+
# .github/config/.files.yaml `proprietary`),
1011
# - every push to main (post-merge safety net),
1112
# - on a nightly cron schedule (catches Keycloak image drift, license
1213
# expiry, upstream proprietary changes),
@@ -15,49 +16,26 @@ name: Enterprise E2E (Playwright)
1516
# Auto-skipped when secrets.PREMIUM_KEY_ENTERPRISE is missing (forks, dependabot).
1617

1718
on:
19+
workflow_call:
1820
push:
1921
branches: ["main"]
20-
pull_request:
21-
branches: ["main"]
22-
merge_group:
23-
branches: ["main"]
2422
schedule:
2523
- cron: "0 4 * * *"
2624
workflow_dispatch:
2725

28-
concurrency:
29-
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
30-
cancel-in-progress: true
26+
# No `concurrency:` block here on purpose. When this workflow is called via
27+
# workflow_call from build.yml, ${{ github.workflow }}/event_name/pr_number
28+
# resolve to the *caller's* values, producing the same group key as build.yml
29+
# and causing the workflow_call instantiation to self-cancel — the job
30+
# silently fails to spawn while `${{ needs.X.result }}` still reports
31+
# `failure`. Standalone runs (push-to-main, nightly cron, dispatch) don't
32+
# overlap often enough to need explicit concurrency control.
3133

3234
permissions:
3335
contents: read
3436

3537
jobs:
36-
files-changed:
37-
name: detect what files changed
38-
runs-on: ubuntu-latest
39-
timeout-minutes: 3
40-
outputs:
41-
proprietary: ${{ steps.changes.outputs.proprietary }}
42-
steps:
43-
- name: Harden Runner
44-
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
45-
with:
46-
egress-policy: audit
47-
- name: Checkout repository
48-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
49-
- name: Check for file changes
50-
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
51-
id: changes
52-
with:
53-
filters: .github/config/.files.yaml
54-
5538
playwright-e2e-enterprise:
56-
# Run on PRs only if relevant files changed; always run on push-to-main,
57-
# cron, and manual dispatch. Fork PRs without the secret will fail at
58-
# the compose step (PREMIUM_KEY empty) — that's intentional, not silent.
59-
if: github.event_name != 'pull_request' || needs.files-changed.outputs.proprietary == 'true'
60-
needs: files-changed
6139
runs-on: ubuntu-latest
6240
timeout-minutes: 45
6341
env:

0 commit comments

Comments
 (0)