Skip to content

Commit 4344f8b

Browse files
committed
Merge branch 'main' of https://github.com/ls1intum/Harmonia into feat/webapp-foundation
2 parents e4aaa33 + d4348a0 commit 4344f8b

34 files changed

+1251
-27
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<!-- Thanks for contributing to Harmonia! Before you submit your pull request, please make sure to check all tasks by putting an x in the [ ] (don't: [x ], [ x], do: [x]). Remove not applicable tasks and do not leave them unchecked -->
2+
<!-- If your pull request is not ready for review yet, create a draft pull request! -->
3+
4+
### Checklist
5+
6+
#### General
7+
8+
<!-- Remove tasks that are not applicable for your PR. Please only put the PR into ready for review, if all relevant tasks are checked! -->
9+
<!-- You only need to choose one of the first two check items: Generally, test on the test servers. -->
10+
<!-- If it's only a small change, testing it locally is acceptable, and you may remove the first checkmark. If you are unsure, please test on the test servers. -->
11+
12+
- [ ] I tested **all** changes and their related features with **all** corresponding user types.
13+
14+
#### Server
15+
16+
- [ ] **Important**: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
17+
- [ ] I **strictly** followed the principle of **data economy** for all database calls.
18+
- [ ] I **strictly** followed the server coding and design guidelines.
19+
- [ ] I documented the Java code using JavaDoc style.
20+
21+
#### Client
22+
23+
- [ ] **Important**: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data (e.g. using paging).
24+
- [ ] I **strictly** followed the principle of **data economy** for all client-server REST calls.
25+
- [ ] I **strictly** followed the client coding and design guidelines.
26+
- [ ] I documented the React code.
27+
28+
### Motivation and Context
29+
30+
<!-- Why is this change required? What problem does it solve? -->
31+
<!-- If it fixes an open issue, please link to the issue here. -->
32+
33+
### Description
34+
35+
<!-- Describe your changes in detail -->
36+
37+
### Steps for Testing
38+
39+
<!-- Please describe in detail how reviewers can test your changes. Make sure to take all related features and views into account! Below is an example that you can refine. -->
40+
41+
Prerequisites:
42+
43+
1. Log in to Harmonia
44+
2.
45+
46+
### Review Progress
47+
48+
<!-- Each PR should be reviewed by at least one other developers. The code, the functionality (= manual test). -->
49+
<!-- The reviewer or author check the following boxes depending on what was reviewed or tested. All boxes should be checked before merge. -->
50+
<!-- You can add additional checkboxes if it makes sense to only review parts of the code or functionality. -->
51+
<!-- When changes are pushed, uncheck the affected boxes. (Not all changes require full re-reviews.) -->
52+
53+
#### Code Review
54+
55+
- [ ] Code Review 1
56+
57+
#### Manual Tests
58+
59+
- [ ] Test 1
60+
61+
### Test Coverage
62+
63+
<!-- Please add the test coverages for all changed files modified in this PR here. -->
64+
<!-- You can execute the tests locally (see build.gradle and package.json) or look into the corresponding artefacts. -->
65+
<!-- The line coverage must be above 90% for changes files, and you must use extensive and useful assertions for server tests and expect statements for client tests. -->
66+
<!-- Note: Confirm in the last column that you have implemented extensive assertions for server tests and expect statements for client tests. -->
67+
<!-- Remove rows with only trivial changes from the table. -->
68+
<!--
69+
| Class/File | Line Coverage | Confirmation (assert/expect) |
70+
|------------|--------------:|-----------------------------:|
71+
| ExerciseService.java | 85% | ✅ |
72+
| programming-exercise.component.ts | 95% | ✅ |
73+
-->
74+
75+
### Screenshots
76+
77+
<!-- Add screenshots to demonstrate the changes in the UI. Remove the section if you did not change the UI. -->
78+
<!-- Create a GIF file from a screen recording in a docker container https://toub.es/2017/09/11/high-quality-gif-with-ffmpeg-and-docker/ -->
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: Validate and Autocommit OpenAPI Spec & Client Code
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'src/main/java/**/*.java'
7+
8+
jobs:
9+
validate-and-commit-openapi:
10+
name: Validate & Autocommit OpenAPI Spec + Client
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
16+
services:
17+
postgres:
18+
image: postgres:17
19+
env:
20+
POSTGRES_DB: harmonia
21+
POSTGRES_USER: postgres
22+
POSTGRES_PASSWORD: harmonia
23+
options: >-
24+
--health-cmd pg_isready
25+
--health-interval 10s
26+
--health-timeout 5s
27+
--health-retries 5
28+
ports:
29+
- 5432:5432
30+
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v5
34+
with:
35+
ref: ${{ github.event.pull_request.head.ref }}
36+
fetch-depth: 0
37+
token: ${{ secrets.BOT_USER_TOKEN }}
38+
39+
- name: Set up Java
40+
uses: actions/setup-java@v5
41+
with:
42+
distribution: 'temurin'
43+
java-version: '25'
44+
45+
- name: Set up Node.js
46+
uses: actions/setup-node@v6
47+
with:
48+
node-version: '24'
49+
cache: 'npm'
50+
cache-dependency-path: 'src/main/webapp/package-lock.json'
51+
52+
- name: Install Node Dependencies
53+
working-directory: src/main/webapp
54+
run: npm ci
55+
56+
- name: Generate OpenAPI Spec
57+
env:
58+
SPRING_PROFILES_ACTIVE: openapi
59+
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/harmonia
60+
SPRING_DATASOURCE_USERNAME: postgres
61+
SPRING_DATASOURCE_PASSWORD: harmonia
62+
SPRING_DATASOURCE_DRIVER_CLASS_NAME: org.postgresql.Driver
63+
SPRING_JPA_HIBERNATE_DDL_AUTO: none
64+
SPRING_LIQUIBASE_ENABLED: false
65+
SPRING_DOCKER_COMPOSE_ENABLED: false
66+
run: ./gradlew generateApiDocs -x webapp
67+
68+
- name: Generate Client Code
69+
run: ./gradlew openApiGenerate
70+
71+
- name: Format Client Code
72+
working-directory: src/main/webapp
73+
run: npx prettier --write src/app/generated
74+
75+
- name: Check for Changes
76+
id: check_changes
77+
run: |
78+
git add openapi/openapi.yaml src/main/webapp/src/app/generated -f
79+
if git diff --cached --quiet; then
80+
echo "no_changes_detected=true" >> $GITHUB_OUTPUT
81+
else
82+
echo "no_changes_detected=false" >> $GITHUB_OUTPUT
83+
fi
84+
85+
- name: Commit OpenAPI + Client changes
86+
if: steps.check_changes.outputs.no_changes_detected == 'false'
87+
run: |
88+
git config --local user.name "github-actions[bot]"
89+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
90+
git commit -m "chore: update OpenAPI spec and generated client"
91+
git push https://x-access-token:${{ secrets.BOT_USER_TOKEN }}@github.com/${{ github.repository }} HEAD:${{ github.event.pull_request.head.ref }}
92+
93+
- name: Comment on PR
94+
run: |
95+
COMMENT=$([[ "${{ steps.check_changes.outputs.no_changes_detected }}" == "true" ]] && echo "🤖 No OpenAPI or client changes needed." || echo "🤖 OpenAPI spec and client code auto-updated and committed.")
96+
curl -s -X POST \
97+
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
98+
-H "Content-Type: application/json" \
99+
-d "{\"body\":\"$COMMENT\"}" \
100+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Check Server Startup
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
check-server-start:
10+
name: Ensure Server Starts Successfully
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 5
13+
14+
services:
15+
postgres:
16+
image: postgres:17
17+
env:
18+
POSTGRES_DB: harmonia
19+
POSTGRES_USER: postgres
20+
POSTGRES_PASSWORD: harmonia
21+
options: >-
22+
--health-cmd pg_isready
23+
--health-interval 10s
24+
--health-timeout 5s
25+
--health-retries 5
26+
ports:
27+
- 5432:5432
28+
29+
steps:
30+
- name: Checkout code
31+
uses: actions/checkout@v5
32+
33+
- name: Setup Gradle
34+
uses: gradle/actions/setup-gradle@v5
35+
with:
36+
gradle-version: '9.2.0'
37+
38+
- name: Set up Java
39+
uses: actions/setup-java@v5
40+
with:
41+
distribution: 'temurin'
42+
java-version: '25'
43+
44+
- name: Start Spring Boot and check log
45+
run: |
46+
./gradlew bootRun > boot.log 2>&1 & SERVER_PID=$!
47+
48+
# Wait for a few seconds to let server start
49+
sleep 240
50+
51+
# Kill the process to avoid timeout
52+
kill $SERVER_PID || true
53+
54+
# Look for Spring Boot banner
55+
if grep -q "Tomcat started on port 8080" boot.log; then
56+
echo "✅ Spring Boot started successfully."
57+
else
58+
echo "❌ Server did not start successfully!"
59+
cat boot.log
60+
exit 1
61+
fi
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: 'Validate Gradle Wrapper'
2+
on:
3+
push:
4+
branches:
5+
- main
6+
paths:
7+
- '**/gradle/**'
8+
pull_request:
9+
branches: [main]
10+
paths:
11+
- '**/gradle/**'
12+
13+
jobs:
14+
validation:
15+
name: 'Gradle Wrapper Validation'
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v5
19+
- uses: gradle/actions/wrapper-validation@v5
20+
with:
21+
min-wrapper-count: 1

.github/workflows/test.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
paths-ignore:
6+
- 'README.md'
7+
- 'CODE_OF_CONDUCT.md'
8+
- 'CONTRIBUTING.md'
9+
- 'LICENSE'
10+
- 'SECURITY.md'
11+
- '../../docs-github/**'
12+
- '.github/**'
13+
- '!.github/workflows/test.yml'
14+
push:
15+
branches:
16+
- main
17+
tags: '[0-9]+.[0-9]+.[0-9]+'
18+
paths-ignore:
19+
- 'README.md'
20+
- 'CODE_OF_CONDUCT.md'
21+
- 'CONTRIBUTING.md'
22+
- 'LICENSE'
23+
- 'SECURITY.md'
24+
- '../../docs-github/**'
25+
- '.github/**'
26+
- '!.github/workflows/test.yml'
27+
release:
28+
types:
29+
- created
30+
31+
# Limit the number of concurrent runs to one per PR
32+
# If a run is already in progress, cancel it
33+
# If the run is not for a PR, then this limit does not apply
34+
concurrency:
35+
group: test-${{ github.head_ref || github.run_id }}
36+
cancel-in-progress: true
37+
38+
# Keep in sync with codeql-analysis.yml and build.yml
39+
env:
40+
CI: true
41+
node: 24
42+
java: 25
43+
# Run all tests for non-draft pull-requests or the default branch. Otherwise, only module-affected tests are run.
44+
RUN_ALL_TESTS: ${{ (github.event_name == 'pull_request' && github.event.pull_request.draft == false) || github.event.repository.default_branch == github.ref_name }}
45+
46+
jobs:
47+
server-style:
48+
runs-on: ubuntu-latest
49+
timeout-minutes: 30
50+
steps:
51+
- uses: actions/checkout@v5
52+
- name: Setup Java
53+
uses: actions/setup-java@v5
54+
with:
55+
distribution: 'temurin'
56+
java-version: '${{ env.java }}'
57+
cache: 'gradle'
58+
- name: Java Code Style
59+
run: ./gradlew spotlessCheck
60+
- name: Java Documentation
61+
run: ./gradlew checkstyleMain -x webapp
62+
if: success() || failure()
63+
64+
client-style:
65+
runs-on: ubuntu-latest
66+
timeout-minutes: 30
67+
defaults:
68+
run:
69+
working-directory: src/main/webapp
70+
steps:
71+
- uses: actions/checkout@v5
72+
- name: Setup Node.js
73+
uses: actions/setup-node@v6
74+
with:
75+
node-version: '${{ env.node }}'
76+
cache: 'npm'
77+
cache-dependency-path: 'src/main/webapp/package-lock.json'
78+
- name: Install Dependencies
79+
run: npm install
80+
- name: TypeScript Formatting
81+
run: npm run prettier:check
82+
- name: TypeScript Code Style
83+
run: npm run lint
84+
if: success() || failure()
85+
86+
client-compilation:
87+
runs-on: ubuntu-latest
88+
timeout-minutes: 5
89+
defaults:
90+
run:
91+
working-directory: src/main/webapp
92+
steps:
93+
- uses: actions/checkout@v5
94+
- name: Setup Node.js
95+
uses: actions/setup-node@v6
96+
with:
97+
node-version: '${{ env.node }}'
98+
cache: 'npm'
99+
cache-dependency-path: 'src/main/webapp/package-lock.json'
100+
- name: Install Dependencies
101+
run: npm install
102+
- name: Compile TypeScript Files With Typechecking
103+
run: npm run compile:ts
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Validate PR Title
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, ready_for_review, edited]
6+
7+
jobs:
8+
validate-pr-title:
9+
runs-on: ubuntu-latest
10+
timeout-minutes: 1
11+
steps:
12+
- uses: Slashgear/action-check-pr-title@v5.0.1
13+
with:
14+
regexp: '^`(Usability|Performance|Development|General)`:\s[A-Z].*$'

0 commit comments

Comments
 (0)