Compare commits

..

257 Commits

Author SHA1 Message Date
64df38f2a9 fix(build): minor haskell typos/errors
The code was written without having a working compiler, hence some accidental code kinks remained.
2025-03-28 08:58:35 +01:00
3c6a580808 chore(git): add ghci history to gitignore 2025-03-28 08:52:58 +01:00
a3762ce938 Merge branch 'master' of https://dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive 2025-03-28 08:33:22 +01:00
573abcf43f refactor(lms): fix hlint suggestions 2025-03-28 08:32:30 +01:00
89d2462974 Merged PR 18750: refactor haskell build container 2025-03-27 12:09:47 +00:00
599d2c1c7a build(backend/Dockerfile): switch to custom-built haskell/stack Dockerfile to supply missing LLVM 2025-03-27 12:52:49 +01:00
d2105c8894 build(backend/Dockerfile): prevent chown of backend files by allow-different-user in stack config 2025-03-27 12:52:07 +01:00
7b486702f4 Add map creating utility after merge confligt 2025-03-27 11:33:06 +00:00
bf88b19f1c Merged PR 18721: chore(tutorial): granting qualification automatically picks better expiry date
chore(tutorial): granting qualification automatically picks better expiry date

Previously, the form for granting tutorial users a qualification suggested the minimum of all expiry dates, if there where several course qualficiations. This lead to some users being granted driving licences being valid for only one month.

The expiry date can now be left blank, using the validDuration of the selected qualification instead.

The default is blank, if there are more than one course qualification having disagreeing qualification dates.
2025-03-27 11:29:18 +00:00
5fd52768bc build(Makefile): add list-projects target 2025-03-27 11:35:01 +01:00
123e9eb057 build(Makefile): fix shell and ghci targets for entrypoint 2025-03-27 11:30:54 +01:00
5ab47c6c4f chore: update gitignore [skip ci] 2025-03-27 11:30:05 +01:00
fd6ba5b0c5 build(backend/Dockerfile): add ENTRYPOINT to support launching ghci with given SRC, etc. 2025-03-27 11:07:14 +01:00
f784f645a6 docs(Makefile): add missing help entries for shell and ghci 2025-03-27 11:06:15 +01:00
92ff99a36e chore(tutorial): granting qualification automatically picks better expiry date
Previously, the form for granting tutorial users a qualification suggested the minimum of all expiry dates, if there where several course qualficiations. This lead to some users being granted driving licences being valid for only one month.

The expiry date can now be left blank, using the validDuration of the selected qualification instead.

The default is blank, if there are more than one course qualification having disagreeing qualification dates.
2025-03-26 16:58:07 +01:00
5a5e4886b7 fix(build): merge from 145-build-system-rewrite neglected newer files
some directories were moved, which ignored files added later on
2025-03-25 18:23:00 +01:00
506b26ddd5 Merged PR 18679: build(Makefile): hard-kill containers before cleaning images
build(Makefile): hard-kill containers before cleaning images
2025-03-25 16:46:14 +00:00
aa664a5822 build(Makefile): hard-kill containers before cleaning images 2025-03-25 17:45:54 +01:00
487069b29e Merged PR 18678: build(Makefile): start: exec instead of run
build(Makefile): start: exec instead of run
2025-03-25 16:41:23 +00:00
f5d701a871 build(Makefile): start: exec instead of run 2025-03-25 17:41:07 +01:00
579ea86503 Merged PR 18677: build(Makefile): launch bash in shell-$SERVICE; add ghci target
build(Makefile): launch bash in shell-$SERVICE; add ghci target
2025-03-25 16:27:50 +00:00
9c1b074adf build(Makefile): launch bash in shell-$SERVICE; add ghci target 2025-03-25 17:27:21 +01:00
a01398f1db Merged PR 18675: add shell-service 2025-03-25 16:16:51 +00:00
020486819f build(Makefile): add shell-$SERVICE target 2025-03-25 17:15:31 +01:00
cd8a7a8322 build(compose.yaml): fix backend binary path bind; add bin path to PATH 2025-03-25 16:52:32 +01:00
79e0d5a642 Merged PR 18666: Update to docker compose 2025-03-25 15:21:18 +00:00
27c5f61299 build(compose.yaml): restrict help service permissions 2025-03-25 15:51:41 +01:00
69b5818427 build(Makefile): remove images too on clean-all 2025-03-25 15:46:39 +01:00
e5e7612e9b build(Makefile): Clean containers on clean-all 2025-03-25 15:44:00 +01:00
ebf71b7135 build(compose.yaml): fix help command 2025-03-25 15:34:14 +01:00
e7c7ec7a82 docs(Makefile): add help messages 2025-03-25 15:33:45 +01:00
d55efd77f7 build(Makefile): rework help and clean 2025-03-25 15:20:21 +01:00
72f5a9fb37 build: move backend-related files into backend dir; implement and connect services via docker-compose
TODOs left: reimplement clean and help, sync static,well-known and assets between services
2025-03-23 04:52:49 +01:00
f1ec60a5b6 build: start to rewrite containerized-Makefile logic for docker-compose; restructure frontend build 2025-03-23 01:44:38 +01:00
5c01ea36c1 chore(release): 27.4.59-0.0.20+145-build-system-rewrite 2025-03-19 02:19:27 +01:00
26b34eee15 build(docker/backend): disable tlmgr for now, to be fixed elsewhere 2025-03-19 02:19:17 +01:00
efa55c8f72 Merged PR 18403: Static ports for development
Commit babee7af: build(Makefile): use static port and dir settings for memcached, minio and maildev
2025-03-18 13:57:20 +00:00
babee7afa2 build(Makefile): use static port and dir settings for memcached, minio and maildev 2025-03-18 14:02:46 +01:00
0cee6f01e8 build(Makefile): fortify PROD var 2025-03-18 14:02:09 +01:00
fdd4283b0d Merged PR 18302: Various Container Fixes
- SET_IMAGE problem fixed
- Static files via memcached
2025-03-17 12:03:42 +00:00
0ac972bf22 chore(release): 27.4.59-0.0.19+145-build-system-rewrite 2025-03-17 10:18:25 +01:00
f40818c1cc build(docker/backend): tlmgr init-usertree 2025-03-17 10:18:06 +01:00
d33a792045 build(Makefile): remove SET_IMAGE in favour of LOCAL_CONTAINERFILE; use non-local postgres with launch args 2025-03-17 10:15:16 +01:00
9ce3b5d146 chore(release): 27.4.59-0.0.18+145-build-system-rewrite 2025-03-17 09:41:54 +01:00
570cfc238b fix(static): fix addStaticContent by using memcached again to supply static files 2025-03-14 20:19:26 +01:00
4fb7a71cfc Merged PR 18230: build(frontend): fix frontend manifest generation
build(frontend): fix frontend manifest generation
2025-03-13 14:05:37 +00:00
b8f6581064 build(frontend): fix frontend manifest generation 2025-03-12 01:21:13 +01:00
c9613e2982 fix(docker): add latex packages to backend container 2025-03-11 17:45:04 +01:00
19c64616f0 fix(build): changing tlmgr setup 2025-03-11 17:06:23 +01:00
e403b6bfb2 Merge branch 'master' of https://dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive 2025-03-11 16:26:32 +01:00
87da02048c Merged PR 18093: build(docker/backend): install texlive only for use with tlmgr; setup tlmgr
build(docker/backend): install texlive only for use with tlmgr; setup tlmgr
2025-03-11 15:25:19 +00:00
3dc74de68e fix(job): jobworkers not working due to dev-settings 2025-03-11 16:21:13 +01:00
b4f85f155a chore(make): add start maildev to start 2025-03-11 16:20:13 +01:00
a97dc071a3 chore(job): add interface for sleep job adding 2025-03-11 12:28:43 +01:00
ee5a79398f chore(job): add sleep job for testing
also show running job workers
2025-03-10 18:24:17 +01:00
e069d6be46 build(docker/backend): install texlive only for use with tlmgr; setup tlmgr 2025-03-10 17:38:30 +01:00
6b32cddeac Merged PR 18029: merge maildev 2025-03-10 16:01:24 +00:00
553e699b56 build(Makefile): add maildev target for local testing 2025-03-10 16:31:33 +01:00
479e807d6d Merged PR 18025: Mail search function implemented
- searching emails
- show course qualification in separate columns

Related work items: #2978, #2979
2025-03-10 15:16:12 +00:00
9d1a97172e fix(tutorial): fix #2978 by having one column per course qualification 2025-03-10 15:57:06 +01:00
24196cc2cd fix(mail): day filtering working in comms center 2025-03-10 12:01:43 +01:00
9ba7a82449 fix(mail): fix #2979 by completing simple mail resent function 2025-03-10 11:41:48 +01:00
695bd18763 build(Makefile): implement compile-release for local release container builds 2025-03-08 16:13:07 +01:00
7e61e56ae1 chore(mail): towards #2979 by providing simple mail resent function 2025-03-07 18:00:55 +01:00
207a304192 chore(mail): towards #2979 by allowing to filter by content in mail center 2025-03-07 17:54:05 +01:00
1b8c6c33a7 chore(latex): try latex-full
does not work either :(
2025-03-07 15:25:02 +01:00
bee015c1f2 fix(job): reenable full jobworkers for test settings 2025-03-07 15:24:04 +01:00
1521d08355 chroe(latex): adjust dockerfiles to be similar with respect to latex 2025-03-06 18:23:11 +01:00
bb047da360 Merge branch '145-build-system-rewrite' 2025-03-06 16:17:10 +01:00
6f90c04b1b build(Makefile): only call make in containers when appropriate; use SET_IMAGE for postgres 2025-03-06 16:16:26 +01:00
1633c41b1d Merged PR 17901: build(Makefile): add dependencies targets as explicit prerequisite for compil...
build(Makefile): add dependencies targets as explicit prerequisite for compiles and starts
2025-03-06 10:58:34 +00:00
20faec8973 build(Makefile): add dependencies targets as explicit prerequisite for compiles and starts 2025-03-06 11:31:40 +01:00
65cb75921d Merged PR 17873: fix yesod-bin
build(Makefile): move yesod-bin and hpack installs to dependencies-backend for more robustness
2025-03-06 07:41:40 +00:00
8104ce96cc build(Makefile): move yesod-bin and hpack installs to dependencies-backend for more robustness 2025-03-05 18:09:48 +01:00
396b365a31 build(Makefile): make backend compiles/starts dependent on .stack target 2025-03-05 18:07:37 +01:00
ff3d33bbf4 build(docker/backend): switch from Dockerfile-based yesod-bin+hpack install to Makefile-based install 2025-03-05 18:05:37 +01:00
82ea44c63f build(docker/backend): use non-mounted directory as stack root; install yesod-bin and hpack in CI too 2025-03-05 17:07:52 +01:00
926dbae09a Merged PR 17790: build(Makefile): really clean everything on clean-all
build(Makefile): really clean everything on clean-all
2025-03-04 15:41:01 +00:00
eb67136c0c build(Makefile): really clean everything on clean-all 2025-03-04 16:35:58 +01:00
b37954d452 Merged PR 17760: build(docker/backend): try backend build without chmod to avoid filemode diffs
build(docker/backend): try backend build without chmod to avoid filemode diffs
2025-03-04 12:43:40 +00:00
5752b4b8da build(docker/backend): try backend build without chmod to avoid filemode diffs 2025-03-04 13:24:30 +01:00
3929bccd6e Manual copy from branch 145-build-system-rewrite due to botched-merge 2025-03-03 11:56:07 +01:00
aae5a5f997 fix spdx copyright year having 2 digits only 2025-03-03 11:44:03 +01:00
1fc948711a Manual copy from branch merge-rewrite-jost due to botched-merge 2025-03-03 11:32:14 +01:00
088587549d chore(profile): show examiners in profile data, towards #2347 2025-03-03 10:47:59 +01:00
bc63324ddf chore(profile): towards exam table in profile data (WIP)
towards #2347
2025-03-03 10:46:53 +01:00
9a12e00f7f refactor(i18n): make SomeMessages more flexible to distinguish it from UniWorXMessages, deprecated the latter 2025-02-28 19:02:28 +01:00
06cd87f360 fix(umlaut): renamee files with german umlaut for ease of use 2025-02-28 18:47:52 +01:00
095002637f chore(qualification): prepare stub for edit handler
also fix some minor navigation issues
2025-02-28 17:29:23 +01:00
ffae8553d5 fix(day): fix #2347 by adding repeated examiner check to day consistency check for day exam occurrences 2025-02-28 17:26:33 +01:00
2ad61c73f1 fix(day): fix #2347 by adding repeated examiner check to day consistency check for day exam occurrences 2025-02-28 17:12:48 +01:00
7dcd0b7297 chore(profile): show examiners in profile data, towards #2347 2025-02-28 17:12:48 +01:00
5881973906 chore(exams): allow email for exam result entry as well 2025-02-28 17:12:48 +01:00
d7dcf0acf5 fix(widgets): fix erroneous whitespace in name widget 2025-02-28 17:12:48 +01:00
1f484f7781 chore(profile): towards exam table in profile data (WIP)
towards #2347
2025-02-28 17:12:48 +01:00
9fbab25ecc chore(tutorial): assigning exam occurrences may check duplicate examiners
towards #2347
2025-02-28 17:12:48 +01:00
be18af08c6 chore(tutorial): user view warns against duplicate examiners
towards #2347
2025-02-28 17:12:48 +01:00
b12de8be15 refactor(admin): problem caching indicator made human readable 2025-02-28 17:12:48 +01:00
4156b3b553 chore(avs): add debug log info after not finding an error in company supervision switching after avs update 2025-02-28 17:09:03 +01:00
7b7c0d4053 fix(linter): disable unnecessary linter warning 2025-02-28 17:09:03 +01:00
6441bc5562 chore(firm): finalize supervision discrepancy view 2025-02-28 17:09:03 +01:00
2a1cff4cd0 fix(build) 2025-02-28 17:09:03 +01:00
aefafa32d1 chore(firm): filter working on supervision discrepancy view 2025-02-28 17:09:03 +01:00
8e0eb401b5 chore(admin): minor reorder admin problem page 2025-02-28 17:09:03 +01:00
8adcdf69fe refactor(db): widen the type for DBRead for more flexibility also - change some AdminProblemR DB actions to DBRead instead - add insane supervision warning to AdminProblem page 2025-02-28 17:09:03 +01:00
d6b4afe975 chore(firm): add working view for supervision discrepancy by firm
show if a supervisionship-company is unrelated to either supervisor or supervisee
2025-02-28 17:09:03 +01:00
cce4b2b27d chore(lms): fix #2605
- Implement a mechanism that deletes those users after a short while
- Never delete numerical LMS logins
- Allow admins to terminate an E-Learning manually
- Option to terminate E-Learning upon longtime renewal
- Detection of unnecessary E-Learning (i.e. long valid durations)
2025-02-28 17:08:59 +01:00
12e01238c4 fix(lms): do not delete orphans with all numerical idents
lms idents with all numerical idents are used for testing and thus should not be deleted, even if orphaned
2025-02-28 17:08:05 +01:00
130f592491 chore(lms): add longter,m validity filter, towards #2605 2025-02-28 17:08:05 +01:00
d1dcdcfe91 fix(avs): updateReceivers should not re-insert formerly known receivers 2025-02-28 17:08:05 +01:00
5e0df28444 chore(mail): view page for receivers working now and polished 2025-02-28 17:08:05 +01:00
0a4ad611c7 chore(mail): add i18n for mail receivers view 2025-02-28 17:08:05 +01:00
2109996387 Added de-de-formal.hamlet for receivers 2025-02-28 17:08:05 +01:00
4f5c7d56b0 chore(mail): add modal computing actual receivers at postal pref columns 2025-02-28 17:08:05 +01:00
05bc06df47 chore(firm): add company preference for email pin passwords
companies may be set such that their users have no email pin password by default
switching to such a company deletes the pin password
2025-02-28 17:07:51 +01:00
38606949b0 chore(lms): implement lms termination action
also:
- track last LmsSate for orphans
- make note searchable

towards #2605
2025-02-28 17:06:33 +01:00
f3f2f397fc fix(audit): add user id who caused company superior change to audit log 2025-02-28 17:06:12 +01:00
d06bc10408 fix(tutorial): truly fix #2696 template choice respects school, course, term, etc.
Template course names may contain Vorlage or Template and the type in any order somewhere within the name
2025-02-28 17:05:54 +01:00
490b89e174 refactor(lms): use runDBRead and caching for FilterColumnHandler used in LMS Orphans 2025-02-28 17:05:54 +01:00
d5bbec9fa3 chore(lms): complete view for orphaned lms logins
towards #2605
2025-02-28 17:05:54 +01:00
fbd99f2394 chore(lms): add note to orphans and create working filter 2025-02-28 17:05:54 +01:00
593ee2cf76 fix(build): remove erroneous + from settings.yml 2025-02-28 17:05:54 +01:00
2360375385 chore(lms): add route and breadcrumbs for lms oprhan view 2025-02-28 17:05:54 +01:00
56aa06097b chore(lms): create stub for lms oprhan view 2025-02-28 17:05:54 +01:00
e9fefa75bd refactor(lms): ensure days/months in qualification settings are always used correctly and implement settings for orphans
- extensive refactoring for qualification lms settings
- qualificationAuditDuration changed from months to days
- qualificationAuditDuration no longer optional
- qualificationAuditDuration is only used for LMS; clarified
- three new settings:
    + orphan-deletion-days:
    + orphan-deletion-batch:
    + orphan-deletion-repeat-hours:
2025-02-28 17:05:50 +01:00
0ffd594a04 chore(lms): register and display orphaned LMS idents
towards #2605
2025-02-28 17:03:26 +01:00
ab340aa715 chore(avs): test AVSneo problems
AVSneo will no longer have unique AVS CardNo: PersonSearch will return one card per company, all having the same CardNo, but possibly different colors

Test shows that FRADrive will handle this just fine, provided the old AVS workaround firing several requests at once remain in place
2025-02-28 17:02:04 +01:00
5128f9b74c fix(i18n): disambiguate between course-type and type of course both in german and english
- english: course type -> course category = Kursart
- german: Art des Kurses-> Kurstyp = Tutorial-Type
2025-02-28 17:01:03 +01:00
558402ac47 fix(avs): prevent empty contact and status queries 2025-02-28 17:01:03 +01:00
1b35c57660 fix(tutorial): fix #2696 template choice respects school, course, term, etc. 2025-02-28 17:00:55 +01:00
56b8a8de86 refactor(lms): remove now obsolete lms edit stub 2025-02-28 17:00:20 +01:00
48096c6b81 fix(hlint): remove superfluous dollar 2025-02-28 16:59:09 +01:00
e8a21610a4 chore(tutorial): convenience button to show tutorial exam results
required new filter on exam participants page
2025-02-28 16:59:09 +01:00
c1ed89a30b various minor code refactors 2025-02-28 16:59:09 +01:00
cf8fc90db7 chore(qualification): finish qualification edit handler 2025-02-28 16:59:09 +01:00
b26dd285df chore(form): create calendarDiffDaysField 2025-02-28 16:58:46 +01:00
e5cf120af2 refactor(UniWorxMessages): eliminate superfluous whitespace
also: some tutorial code cleaning
2025-02-28 16:56:11 +01:00
ad12b8f927 refactor(tutorial): fix and complete exam occurrence form function 2025-02-28 16:56:11 +01:00
9fe78541d7 refactor(tutorial): exam occurrence form function and appearance 2025-02-28 16:56:11 +01:00
a0604637bd refactor(tutorial): exam occurrence editing received specialised page 2025-02-28 16:56:11 +01:00
5e41c2073f chore(tutorial): add separate exam occurrence edit page (WIP) 2025-02-28 16:56:11 +01:00
50c7d18b53 chore(exam): add convenience function to duplicate exam occurrences to another day 2025-02-28 16:56:11 +01:00
f996976f65 chore(exam): auto name generation for examOccurrences 2025-02-28 16:56:11 +01:00
f04a40c0a3 chore(tutorial): add covenience button to full exam editing 2025-02-28 16:56:11 +01:00
6cc929e377 fix(tutorial): fix exam occurrence form
works better, but still not 100%
some debugging added
2025-02-28 16:56:11 +01:00
11bcef67f8 chore(tutorial): switch relevant exams from registerFrom/To to examStart/End
registering is of users/supervisors, but this page is for admins, so  examStart/examEnd are only relevant for when it is actually happening
2025-02-28 16:56:11 +01:00
7b7ffab109 chore(tutorial): towards #2347 exam occurrence form design finished, but buggy somehow (WIP)
Propably due to multiActionAForm badly interacting with contained massInputForm
2025-02-28 16:56:11 +01:00
afbeb86762 chore(pathpiecel): PathPiece instance for lists of exam occurrence ids
towards #2347
2025-02-28 16:56:11 +01:00
9af4a3a22e chore(tutorial): towards #2347 exam occurrence form mostly working (WIP)
form is completed, but the initial call needs proper arguments from DB about all apropriate exams
2025-02-28 16:56:11 +01:00
4241c75afe chore(tutorial): towards #2347 exam occurrence form added (WIP) 2025-02-28 16:56:11 +01:00
afa2f9bf0e chore(tutorial): towards #2347 add convenience buttons to add exam tutorial (STUB)
This is STUB add a multiform action that is not yet evaluated. Form Handler is to be implemented next.
2025-02-28 16:56:11 +01:00
f44d66cb91 chore(tutorial): assign exam rooms for tutorial users ad hoc 2025-02-28 16:56:11 +01:00
1d68ed9c5e refactor(saltine): fix hlint and ghc warnings 2025-02-28 16:56:07 +01:00
cd84d0a932 refactor(daily): move caching into own submodule
we need those methods in Handler.Tutorial.Users as well
2025-02-28 16:54:19 +01:00
f467f6086e chore(daily): add function to retrieve all exam occurrences for given days
the function uses the memcachedByClass mechanism, which was slightly refined as well to include the class within the memcached keys for added correctness
2025-02-28 16:53:34 +01:00
4f524bd8d2 refactor(form): make all userField variants consistent with each other 2025-02-28 16:53:20 +01:00
aaf72f7255 chore(exam): show exam occurrences in participants views for tutorial and course 2025-02-28 16:53:20 +01:00
36a3b04ad8 chore(exam): add examiner to occurrence options
we intend to use the exam examiner for adding occurrences through tutorials
2025-02-28 16:53:20 +01:00
ae6d3b0fc3 fix(form): knownUserField not working as intended (WIP) 2025-02-28 16:53:20 +01:00
6f3dd408bb fix(form): knownUserField not working as intended (WIP) 2025-02-28 16:53:20 +01:00
c0c1665ccb refactor(form): knownUserField not working as intended (WIP) 2025-02-28 16:53:20 +01:00
c2e0f6b2b8 chore(form): add knownUserField accepting known users only 2025-02-28 16:53:20 +01:00
a1d7f16427 fix(fill): exam prefill dates work now 2025-02-28 16:53:20 +01:00
5f3d8a88e2 fix(hlint): implement hlint suggestion 2025-02-28 16:53:20 +01:00
b42e93e891 chore(daily): implement left-over todos and i18n 2025-02-28 16:53:17 +01:00
e53be8ddf9 fix(icons): fix some botched icon definitions, for real 2025-02-28 16:52:22 +01:00
6d583fe8c4 fix(icons): fix some botched icon definitions 2025-02-28 16:52:22 +01:00
954e86c95a fix(ghci): ghci works now as expected 2025-02-28 16:52:17 +01:00
f47528c741 chore(daily): fix #2349 completing daily sanity check 2025-02-28 16:51:10 +01:00
ad1d235bea chore(daily): towards #2347 check complete, except i18n
also missing: displaying memcached check results in each line of day view
2025-02-28 16:50:23 +01:00
d4d915bd60 chore(daily): towards #2347 by caching and sorting results 2025-02-28 16:47:46 +01:00
07cfc0adcb fix(hlint): implement some hlint suggestions 2025-02-28 16:42:37 +01:00
f6c82009ee chore(job): disable jobworkers in development in order to reduce log output 2025-02-28 16:42:37 +01:00
c08d6ae0d0 chore(daily): properly implement note suggestion caching and invalidation 2025-02-28 16:42:37 +01:00
6a0876ae55 chore(daily): basic functionality #1939 completed and checked - filters now work as intended - textField suggestions now work as intended 2025-02-28 16:42:37 +01:00
75a4f52a80 fix(icon): add missing icon 2025-02-28 16:42:27 +01:00
1f7e9b6a2f chore(daily): adjust css, improve suggestions 2025-02-28 16:42:03 +01:00
564488d5fa chore(day): attempt to fix participant note suggestions 2025-02-28 16:40:57 +01:00
500c9a749a chore(daily): add suggestions to note fiels (WIP) 2025-02-28 16:40:57 +01:00
ede00deb86 refactor(daily): user company discrepancies 2025-02-28 16:40:16 +01:00
9eb075836f fix(daily): form submit now works as intended 2025-02-28 16:39:33 +01:00
d546e5da0f minor adjustments to routes and icons 2025-02-28 16:39:33 +01:00
162c44a44f fix(msg): minor uni2wok to fradrive message change
Primarly done to the the new build environment start-backend file watcher and see whether a restart enables the website
2025-02-28 16:39:33 +01:00
0a29540089 fix(doc): Update outdated GitLab references to DevOps work items 2025-02-28 16:39:33 +01:00
6f1ad811f7 chore(firm): add action to add non-avs firm associates 2025-02-28 16:39:33 +01:00
d2f69dc023 fix(doc): minor haddock fixes 2025-02-28 16:39:33 +01:00
cd76bdd4e7 chore(day): complete form columns for daily view (untested)
unfortunately `make start` does not enter DEVELOPMENT mode currently, so this is not yet testeted.
2025-02-28 16:39:33 +01:00
e1dca7d6b0 chore(day): make form columns compile eventually 2025-02-28 16:39:33 +01:00
5d46479a33 chore(icons): add instructions on how to add icons 2025-02-28 16:39:28 +01:00
fcf1b6d9d8 fix(icons): add missing icons 2025-02-28 16:38:58 +01:00
7e09636a2b chore(day): add missing form columns 2025-02-28 16:38:42 +01:00
8317f682d8 chore(tutorial): (WIP) towards #90 write form columns 2025-02-28 16:38:41 +01:00
85511091cc fix(test): fix test problem and add tests for UserEyeExam and UserDrivingPermit 2025-02-28 16:38:41 +01:00
02d10006fc fix(build) 2025-02-28 16:38:41 +01:00
2fdb132140 chore(tutorial): show additional columns for #90
columns are distinguished by user and the entities given in parenthesis:
- driving permit (tutorial)
- eye exam (tutrial)
- tutorial note (tutorial)
- attendance (tutorial & day)
- attendance-note (tutorial & day)
- parking permit (day)
2025-02-28 16:38:41 +01:00
fba0b71d50 chore(tutorial): build model for #90 2025-02-28 16:38:41 +01:00
4934f5f89d fix(room): deduplicate room column and fix order 2025-02-28 16:38:41 +01:00
133a8d3739 chore(daily): show rooms for tutorial lessons 2025-02-28 16:38:41 +01:00
e8af2b8da9 refactor(TH): minor code clean up 2025-02-28 16:38:41 +01:00
ac766ea217 refactor(TH): add sqlMIXproj' using reify on TableExpr for more comfort 2025-02-28 16:38:41 +01:00
a113d43089 chore(TH): add sqlMIXproj to improve dbTable usage, also add card-nos to DayTask Table 2025-02-28 16:38:41 +01:00
14140c982b refactor(memcached): checking memcached key security mechanisms
RESULTS:

Keys for memcached use their Binary representation!

This means that the following three are all interchangeable as a key:
      newtype Foo1 = Foo1 { someInt1 :: Int } deriving newtype (Binary)
      data    Foo2 = Foo2 { someInt2 :: Int } deriving         (Binary)
      type    Foo3 = Int
Therefore it is best to use $(memcachedHere) or $(memcachedByHere) if possible or add another type
2025-02-28 16:38:41 +01:00
ce125b6495 chore(daily): show course associated qualifications 2025-02-28 16:38:41 +01:00
0c78996260 fix(avs): fix #225 by skipping firm updates entirely if AVS FirmInfo is unchanged for previously seen values for AVS User to be updated 2025-02-28 16:38:18 +01:00
b78c898ebf fix(avs): fix #224 repeated superior changes no longer occur
furthermore AdminProblems are only inserted if the same problem does not exist unsolved
2025-02-28 16:35:13 +01:00
4bca7580d0 refactor(occurrences): fold RoomReference into Occurrences, completed 2025-02-28 16:32:52 +01:00
46f777740f fix(memcached): using memcachedHere did not compile due to staging problems 2025-02-28 16:32:52 +01:00
a7b08b1ae5 fix(occurrences): room occurrence form works now 2025-02-28 16:32:52 +01:00
452cdf4442 fix(test): add arbitrart instances and adjust argument changes to tests 2025-02-28 16:32:52 +01:00
f6b87a09b0 fix(build): occurrences no longer have a READ instance 2025-02-28 16:32:52 +01:00
0a5b0fceff chore(build): limit max compile cpu cores to 5 2025-02-28 16:32:52 +01:00
3e6717904a chore(occurrences): workaround provide simple room field with least recent suggestions 2025-02-28 16:32:52 +01:00
2059d678ee refactor(memcached): remove ARC cache and LRU logic some more
more leftover dead code was removed, especially cache prewarm options that no longer had an effect on a non-existing ARC cache
2025-02-28 16:32:52 +01:00
225af31943 chore(occurrences): add GIN index for JSONB columns 2025-02-28 16:32:52 +01:00
9d26c1c171 refactor(occurrences): fix migration 2025-02-28 16:32:52 +01:00
22d6cf737e refactor(occurrences): remove RoomReference from model and add migration 2025-02-28 16:32:52 +01:00
35cadda2e8 refactor(occurrences): fold RoomReference into Occurrences (WIP)
Each Occurrence now has its own RoomReference, i.e. Mondays may have a different Room assigned than Tuesdays

WIP Problem: occurrencesAFrom does not work, always insists on Room missing
2025-02-28 16:32:52 +01:00
692350677f fix(build): minor 2025-02-28 16:32:52 +01:00
36b481a548 fix(occurrences): occurringLessons had an erroneously inverted condition 2025-02-28 16:32:52 +01:00
cb58c20ca1 chore(occurrences): add datatype LessonTime for dealing timetable intervals 2025-02-28 16:32:52 +01:00
e757209b80 refactor(memcached): remove ARC cache entirely
NOTE: this was a crude surgery, removing everything ARC related; some dead code artifacts may have remained.

Especially check PrewarmCacheConf

Reason for removall: adding `memcachedInvalidateClass` was difficult to implement with ARC active; ARC was known to be problematic; removal was easier (see #2 2024-09-23)
2025-02-28 16:32:25 +01:00
74c330bd24 chore(memcached): add key classes for easy invalidation 2025-02-28 16:29:45 +01:00
cac0a47d01 refactor(daily): factor our tutorial selection function 2025-02-28 16:25:43 +01:00
5c70b1099c fix(firm): filtering by active supervisor working 2025-02-28 16:25:43 +01:00
26ea39dc67 fix(lpr): print log sorting works now 2025-02-28 16:25:43 +01:00
2385d989a8 fix(build) 2025-02-28 16:25:43 +01:00
0105aa8c3f refactor(model): move JSONB instance to proper module 2025-02-28 16:25:43 +01:00
3bae365b37 chore(lpr): improve lpr log display 2025-02-28 16:25:43 +01:00
1d01897757 chore(daily): make company a property of TutorialParticipant, towards #90 2025-02-28 16:25:43 +01:00
ce62b99d2b chore(daily): add more columns #90 2025-02-28 16:25:43 +01:00
4dbe005709 chore(daily): add page actions #90 2025-02-28 16:25:43 +01:00
11ef856b2b refactor(jsonb): change DB using JSONB, to improve stub #90 2025-02-28 16:25:43 +01:00
5a03d1cabe chore(daily): improve stub #90 change DB to JSONB (WIP) 2025-02-28 16:25:43 +01:00
0264c87510 chore(daily): create stub in preparation for #90 2025-02-28 16:25:43 +01:00
e9a4c838a8 refactor(map): clarify some unnecessarily obfuscated code
also, using Map.fromList is more efficient if the list happens to be ordered
2025-02-28 16:25:43 +01:00
733324a732 chore(config): add config/develop-settings.yml only active if DEVELOPMENT
Ensure that certain settings are NOT seen in production, but automatically active in development without using environment variables.
2025-02-28 16:25:43 +01:00
757d383d33 chore(gitlab-ci): install and decode font ttfs 2025-02-28 15:56:15 +01:00
ee02a50bdd chore(node-deps): add ttf2woff as dev dep 2025-02-28 15:55:40 +01:00
c859974495 chore(gitignore): do not publish font files (for now) 2025-02-28 15:51:59 +01:00
ce35c8efc9 Merge branch '145-build-system-rewrite' 2025-02-28 15:37:36 +01:00
3151be6f41 build(Makefile): add documentation 2025-02-21 12:49:35 +01:00
e90d11682b fix(lms): eliminate unlikely possible discrepancy for LMS deletion indicator
It was theoretically possible for LMS Learner deletion tag to be not correctly shown in LMS table.

Also see #2605 for further related issues.
2025-01-10 16:49:53 +01:00
9a281f040e fix(print): apcidents somehow include newlines after DB update; strip these 2024-11-18 12:36:05 +01:00
0b70036a02 fix(LMS): fix #2235 by notifying LMS user upon reset 2024-11-08 13:47:16 +01:00
3b0029ba04 fix(avs): fix #225 by skipping firm updates entirely if AVS FirmInfo is unchanged for previously seen values for AVS User to be updated 2024-10-09 12:50:32 +02:00
e554048f5a fix(avs): avs firm update no longer may update wrong company
Note: noticed while working on #225
2024-10-09 12:50:32 +02:00
e59fff352f fix(avs): fix #224 repeated superior changes no longer occur
furthermore AdminProblems are only inserted if the same problem does not exist unsolved
2024-10-09 12:50:32 +02:00
e9d4174b83 chore(release): 27.4.79 2024-09-10 17:56:40 +02:00
90613faf72 Merge branch 'fradrive/jost' 2024-09-10 17:55:52 +02:00
d92d23bc99 chore(release): 27.4.78 2024-09-05 17:55:54 +02:00
4959736c90 Merge branch 'fradrive/jost' 2024-09-05 17:55:09 +02:00
547f34d2ec chore(release): 27.4.77 2024-09-02 10:50:31 +02:00
08788427a8 Merge branch 'fradrive/jost' into 'master'
HOTFIX(avs): switch company did not always increase priority

Closes #175 and #174

See merge request fradrive/fradrive!41
2024-09-02 08:42:32 +00:00
6d1b177ce9 Merge branch 'fradrive/jost' into 'master'
Fradrive/jost - two minor fixes

See merge request fradrive/fradrive!40
2024-08-26 18:04:38 +00:00
e1a02879d6 Merge branch 'fradrive/jost' into 'master'
chore(health): augement #154 by adding option to disable interface warnings

See merge request fradrive/fradrive!39
2024-08-22 18:08:52 +00:00
97446aa9ef Merge branch 'fradrive/jost' into 'master'
minor update

Closes #154 and #5

See merge request fradrive/fradrive!38
2024-08-21 17:59:22 +00:00
776e6b6736 Merge branch 'fradrive/jost' into 'master'
AVS automatic synchronisation

See merge request fradrive/fradrive!37
2024-08-12 18:29:21 +00:00
1304 changed files with 20646 additions and 20330 deletions

View File

@ -0,0 +1,65 @@
# SPDX-FileCopyrightText: 2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: releaseTag
type: string
- name: releaseEndpoint
type: string
default: 'devfra'
values:
- 'devfra'
- 'prodfra'
jobs:
- job: Release
displayName: Release ${{ parameters.releaseTag }}
container:
image: devfra.azurecr.io/de.fraport.build/tools:1.1.0
endpoint: devfra
steps:
# Download required artifacts from pipeline
- task: DownloadPipelineArtifact@2
displayName: Download FraDrive binaries
inputs:
artifactName: Build_backend
patterns: 'Build_backend/bin/*'
targetPath: '$(Build.Repository.LocalPath)'
- task: Docker@2
displayName: Login to container registry
inputs:
command: login
containerRegistry: '${{ parameters.releaseEndpoint }}'
- task: Bash@3
displayName: Build FraDrive container
inputs:
targetType: inline
script: |
cp docker/fradrive/Dockerfile .
docker build \
--tag $(buildImageUpstream)/fradrive:$(Build.BuildNumber) \
--tag $(buildImageUpstream)/fradrive:${{parameters.releaseTag}} \
--build-arg FROM_IMG=devfra.azurecr.io/de.fraport.trusted/ubuntu \
--build-arg FROM_TAG=20.04 \
--build-arg PROJECT_DIR=$(Build.Repository.LocalPath) \
--build-arg IN_CI=true \
--build-arg IN_CONTAINER=true \
--build-arg HTTPS_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg HTTP_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg NO_PROXY='localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io' \
--build-arg FRAPORT_NOPROXY=dev.azure.com,*.dev.azure.com,*.fraport.de,*.frankfurt-airport.de \
.
- task: Docker@2
displayName: Push container to registry
inputs:
command: push
repository: 'de.fraport.fradrive.build/fradrive'
tags: '$(Build.BuildNumber),${{parameters.releaseTag}}'
- task: Docker@2
displayName: Logout from container registry
inputs:
command: logout
containerRegistry: '${{ parameters.releaseEndpoint }}'

View File

@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: serviceName
type: string
- name: dependenciesCaches
type: object
default: []
- name: dependenciesBuildPool
type: string
default: 'Prod Private Agent Pool'
values:
- 'Prod Private Agent Pool'
- 'Prod Private Agent Pool DS2'
- 'Prod Private Agent Pool DS3'
- name: dependenciesBuildCores
type: number
default: 1
- name: dependenciesBuildTimeout
type: number
default: 60
jobs:
- job: SetupDependencies_${{parameters.serviceName}}
displayName: Install ${{parameters.serviceName}} dependencies
dependsOn: SetupImage_${{parameters.serviceName}}
${{ if eq(variables.setupImages, true) }}:
condition: succeeded()
${{ else }}:
condition: always()
pool: '${{parameters.dependenciesBuildPool}}'
timeoutInMinutes: ${{parameters.dependenciesBuildTimeout}}
container:
${{ if variables.setupImages }}:
image: $(buildImageUpstream)/${{parameters.serviceName}}:$(Build.BuildNumber)
${{ else }}:
image: $(buildImageUpstream)/${{parameters.serviceName}}:latest
endpoint: devfra
env:
PROJECT_DIR: $(Build.Repository.LocalPath)
IN_CONTAINER: true
IN_CI: true
steps:
# Restore previously-built dependencies from caches
- ${{ each cache in parameters.dependenciesCaches }}:
- template: ./../../steps/cache.yaml
parameters:
cacheIdent: '${{parameters.serviceName}}-dependencies'
cacheKeys: '${{cache.key}}'
cachePath: '${{cache.path}}'
# Compile dependencies
- template: ./../../steps/make.yaml
parameters:
makeJob: dependencies
makeService: ${{parameters.serviceName}}
makeVars: 'CPU_CORES=${{parameters.dependenciesBuildCores}} STACK_CORES=-j${{parameters.dependenciesBuildCores}}'
# (Note: a post-job for updating the dependency cache is automatically created, so no further step is due here.)

View File

@ -0,0 +1,72 @@
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: imageName
type: string
- name: imageBase
type: object
jobs:
- job: SetupImage_${{parameters.imageName}}
displayName: Build ${{parameters.imageName}} image
condition: eq(variables.setupImages, true)
container:
image: devfra.azurecr.io/de.fraport.build/tools:1.1.0
endpoint: devfra
steps:
- task: Docker@2
displayName: Login to container registry
inputs:
command: login
containerRegistry: devfra
- task: Bash@3
displayName: Build ${{parameters.imageName}} image
inputs:
targetType: inline
script: |
cp docker/${{parameters.imageName}}/Dockerfile .
docker build \
--tag $(buildImageUpstream)/${{parameters.imageName}}:$(Build.BuildNumber) \
--build-arg FROM_IMG=${{parameters.imageBase.image}} \
--build-arg FROM_TAG=${{parameters.imageBase.tag}} \
--build-arg HTTPS_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg HTTP_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg NO_PROXY='localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io' \
--build-arg FRAPORT_NOPROXY=dev.azure.com,*.dev.azure.com,*.fraport.de,*.frankfurt-airport.de \
--build-arg PROJECT_DIR=$(Build.Repository.LocalPath) \
--build-arg IN_CI=true \
--build-arg IN_CONTAINER=true \
.
- task: Bash@3
displayName: Push ${{parameters.imageName}} image
inputs:
targetType: inline
script: |
docker push $(buildImageUpstream)/${{parameters.imageName}}:$(Build.BuildNumber)
- task: Bash@3
displayName: Update latest ${{parameters.imageName}} image
condition: or(eq(variables.forcePushLatest, true), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
inputs:
targetType: inline
script: |
docker tag $(buildImageUpstream)/${{parameters.imageName}}:$(Build.BuildNumber) $(buildImageUpstream)/${{parameters.imageName}}:latest
docker push $(buildImageUpstream)/${{parameters.imageName}}:latest
- task: Bash@3
displayName: Save image for publication
inputs:
targetType: inline
script: |
docker image save --output=$(Build.ArtifactStagingDirectory)/${{parameters.imageName}}.tar $(buildImageUpstream)/${{parameters.imageName}}:$(Build.BuildNumber)
- task: PublishBuildArtifacts@1
displayName: Publish image as artifact
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: Image_${{parameters.imageName}}
publishLocation: 'Container'
- task: Docker@2
displayName: Logout from container registry
inputs:
command: logout
containerRegistry: devfra

View File

@ -0,0 +1,141 @@
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: serviceName
type: string
default: serviceName
- name: serviceBase
type: object
default:
image: baseImage
tag: baseImageTag
- name: servicePool
type: string
default: 'Prod Private Agent Pool'
- name: serviceTimeout
type: number
default: 60
# extraBuildOptions: ''
- name: serviceDependsOn
type: object
default: []
- name: serviceRequiredArtifacts
type: object
default: []
- name: serviceArtifacts
type: string
default: ''
- name: buildSteps
type: object
stages:
- stage: ${{ parameters.serviceName }}
dependsOn: ${{ parameters.serviceDependsOn }}
pool: '${{ parameters.servicePool }}'
jobs:
- job: ImageBuild_${{parameters.serviceName}}
displayName: Build ${{parameters.serviceName}} image
condition: or(eq(variables.forcePushLatest, true), eq(variables.onMasterBranch, true), eq(variables.onUpdateBranch, true))
container:
image: devfra.azurecr.io/de.fraport.build/tools:1.1.0
endpoint: devfra
steps:
- checkout: self
- task: Docker@2
displayName: Login to container registry
inputs:
command: login
containerRegistry: devFra
- script: |
ls -a .
pwd
find .
- task: Bash@3
displayName: Build ${{parameters.serviceName}} image
inputs:
targetType: inline
script: |
cp docker/${{parameters.serviceName}}/Dockerfile .
docker build \
--tag $(buildImageUpstream)/${{parameters.serviceName}}:$(Build.BuildNumber) \
--build-arg FROM_IMG=${{parameters.serviceBase.image}} \
--build-arg FROM_TAG=${{parameters.serviceBase.tag}} \
--build-arg HTTPS_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg HTTP_PROXY=http://proxy.frankfurt-airport.de:8080 \
--build-arg NO_PROXY='localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io' \
--build-arg FRAPORT_NOPROXY=dev.azure.com,*.dev.azure.com,*.fraport.de,*.frankfurt-airport.de \
--build-arg PROJECT_DIR=$(Build.Repository.LocalPath) \
--build-arg IN_CI=true \
--build-arg IN_CONTAINER=true \
.
- task: Bash@3
displayName: Push ${{ parameters.serviceName }} image
inputs:
targetType: inline
script: |
docker push $(buildImageUpstream)/${{parameters.serviceName}}:$(Build.BuildNumber)
- task: Bash@3
displayName: Update latest ${{parameters.serviceName}} image
condition: or(eq(variables.forcePushLatest, true), eq(variables.onMasterBranch, true))
inputs:
targetType: inline
script: |
docker tag $(buildImageUpstream)/${{parameters.serviceName}}:$(Build.BuildNumber) $(buildImageUpstream)/${{parameters.serviceName}}:latest
docker push $(buildImageUpstream)/${{parameters.serviceName}}:latest
- task: Docker@2
displayName: Logout from container registry
inputs:
command: logout
containerRegistry: devFra
- job: Build_${{parameters.serviceName}}
displayName: Build ${{parameters.serviceName}}
dependsOn:
- ImageBuild_${{parameters.serviceName}}
condition: in(dependencies.ImageBuild_${{parameters.serviceName}}.result, 'Succeeded', 'Skipped')
timeoutInMinutes: ${{ parameters.serviceTimeout }}
container:
# TODO: use BuildNumber instead of latest in update branches
# image: devfra.azurecr.io/de.fraport.fradrive.build/frontend:$(Build.BuildNumber)
image: $(buildImageUpstream)/${{parameters.serviceName}}:latest
endpoint: devfra
env:
PROJECT_DIR: $(Build.Repository.LocalPath)
IN_CONTAINER: true
IN_CI: true
steps:
- checkout: self
- ${{ each dependency in parameters.serviceRequiredArtifacts }}:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts from ${{ dependency.name }} dependency
continueOnError: ${{ dependency.continueOnError }}
condition: ${{ dependency.condition }}
inputs:
artifactName: ${{ dependency.artifact }}
source: ${{ dependency.source }}
project: 'Fahrerausbildung'
pipeline: $(System.DefinitionId)
buildVersionToDownload: '${{ dependency.version }}'
tags: '${{ dependency.artifact }}'
allowPartiallySucceededBuilds: true
allowFailedBuilds: true
patterns: '${{ dependency.patterns }}'
targetPath: '$(Build.Repository.LocalPath)'
- ${{ each buildStep in parameters.buildSteps }}:
- template: ./service/build-step.yaml
parameters:
service: ${{ parameters.serviceName }}
buildStep: ${{ buildStep }}
- task: CopyFiles@2
displayName: Copy ${{parameters.serviceName}} artifacts
inputs:
Contents: ${{ parameters.serviceArtifacts }}
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: Publish ${{parameters.serviceName}} artifacts
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: '${{parameters.serviceName}}'
publishLocation: 'Container'

View File

@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: artifactName
type: string
steps:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts from ${{parameters.artifactName}}
inputs:
source: 'current'
artifactName: '${{parameters.artifactName}}'
targetPath: '$(Build.Repository.LocalPath)'

View File

@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: cacheIdent
type: string
- name: cacheKeys
type: string
- name: cachePath
type: string
steps:
- task: Cache@2
displayName: Restore ${{parameters.cacheIdent}} cache
inputs:
key: '"${{parameters.cacheIdent}}" | ${{parameters.cacheKeys}}'
path: '${{parameters.cachePath}}'

View File

@ -0,0 +1,35 @@
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
parameters:
- name: makeJob
type: string
values:
- dependencies
- compile
- lint
- test
- name: makeService
type: string
values:
- frontend
- backend
- name: makeVars
type: string
default: ''
steps:
- task: Bash@3
name: ${{parameters.makeJob}}_${{parameters.makeService}}
displayName: make ${{parameters.makeJob}}-${{parameters.makeService}}
env:
HTTPS_PROXY: http://proxy.frankfurt-airport.de:8080
HTTP_PROXY: http://proxy.frankfurt-airport.de:8080
NO_PROXY: 'localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io'
FRAPORT_NOPROXY: 'dev.azure.com,*.dev.azure.com,*.fraport.de,*.frankfurt-airport.de'
PROJECT_DIR: $(Build.Repository.LocalPath)
inputs:
targetType: inline
script: |
make -- --${{parameters.makeJob}}-${{parameters.makeService}} IN_CONTAINER=true IN_CI=true PROJECT_DIR=${PROJECT_DIR} ${{parameters.makeVars}}

View File

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: 2022 Felix Hamann <felix.hamann@campus.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>
SPDX-License-Identifier: AGPL-3.0-or-later

View File

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>
SPDX-License-Identifier: AGPL-3.0-or-later

21
.gitignore vendored
View File

@ -2,9 +2,12 @@
dist*
develop
node_modules/
assets/icons
assets/favicons
.npm/
.node_repl_history
**/assets/icons
**/assets/favicons
bin/
assets/fonts/
*.hi
*.o
*.sqlite3
@ -39,19 +42,19 @@ src/Handler/Assist.bak
src/Handler/Course.SnapCustom.hs
*.orig
/instance
backend/instance
.stack-work-*
.stack-work.lock
.directory
tags
test.log
*.dump-splices
/.stack-work.lock
/.npmrc
/.npm/
/config/manifest.json
tunnel.log
/static
/well-known
/.well-known-cache
static
well-known
.well-known-cache
manifest.json
/.nix-well-known
/**/tmp-*
/testdata/bigAlloc_*.csv
@ -65,4 +68,4 @@ tunnel.log
**/result-*
.develop.cmd
/.vscode
.ghc/ghci_history
backend/.ghc/ghci_history

View File

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>
SPDX-License-Identifier: AGPL-3.0-or-later

View File

@ -7,33 +7,33 @@ const standardVersionUpdaterYaml = require.resolve('standard-version-updater-yam
module.exports = {
scripts: {
// postbump: './sync-versions.hs && git add -- package.yaml', // moved to bumpFiles
postchangelog: 'sed \'s/^### \\[/## [/g\' -i CHANGELOG.md'
postchangelog: 'sed \'s/^### \\[/## [/g\' -i CHANGELOG.md',
},
packageFiles: ['package.json', 'package.yaml'],
bumpFiles: [
{
filename: 'package.json',
type: 'json'
type: 'json',
},
{
filename: 'package-lock.json',
type: 'json'
type: 'json',
},
{
filename: 'package.yaml',
updater: standardVersionUpdaterYaml
updater: standardVersionUpdaterYaml,
},
{
filename: 'nix/docker/version.json',
type: 'json'
type: 'json',
},
{
filename: 'nix/docker/demo-version.json',
type: 'json'
}
type: 'json',
},
],
commitUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/{{hash}}',
compareUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/{{previousTag}}...{{currentTag}}',
issueUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/{{id}}',
userUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/{{user}}'
userUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/{{user}}',
};

View File

@ -2,6 +2,16 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [27.4.59-0.0.20+145-build-system-rewrite](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/27.4.59-0.0.19+145-build-system-rewrite...27.4.59-0.0.20+145-build-system-rewrite) (2025-03-19)
## [27.4.59-0.0.19+145-build-system-rewrite](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/27.4.59-0.0.18+145-build-system-rewrite...27.4.59-0.0.19+145-build-system-rewrite) (2025-03-17)
## [27.4.59-0.0.18+145-build-system-rewrite](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-g0.0.17...27.4.59-0.0.18+145-build-system-rewrite) (2025-03-17)
### Bug Fixes
* **static:** fix addStaticContent by using memcached again to supply static files ([570cfc2](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/570cfc238bdccd3438124f96290b9272c8e82f0f))
## [v27.4.59-test-g0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-f0.0.17...v27.4.59-test-g0.0.17) (2025-02-18)
## [v27.4.59-test-f0.0.17](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-g0.0.16...v27.4.59-test-f0.0.17) (2025-02-17)
@ -16,6 +26,48 @@ All notable changes to this project will be documented in this file. See [standa
## [v27.4.59-test-f0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.14...v27.4.59-test-f0.0.14) (2025-02-14)
## [v27.4.59-test-e0.0.14](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.13...v27.4.59-test-e0.0.14) (2025-02-13)
## [v27.4.59-test-e0.0.13](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-e0.0.12...v27.4.59-test-e0.0.13) (2025-02-12)
## [v27.4.59-test-e0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.12...v27.4.59-test-e0.0.12) (2025-02-12)
## [v27.4.59-test-d0.0.12](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-d0.0.11...v27.4.59-test-d0.0.12) (2025-02-11)
## [v27.4.59-test-d0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.11...v27.4.59-test-d0.0.11) (2025-02-11)
## [v27.4.59-test-c0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.11...v27.4.59-test-c0.0.11) (2025-02-11)
## [v27.4.59-test-b0.0.11](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-c0.0.10...v27.4.59-test-b0.0.11) (2025-02-11)
## [v27.4.59-test-c0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-b0.0.10...v27.4.59-test-c0.0.10) (2025-02-11)
## [v27.4.59-test-b0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.10...v27.4.59-test-b0.0.10) (2025-02-11)
## [v27.4.59-test-a0.0.10](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.9...v27.4.59-test-a0.0.10) (2025-02-11)
## [v27.4.59-test-a0.0.9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.8...v27.4.59-test-a0.0.9) (2025-02-10)
## [v27.4.59-test-a0.0.8](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.7...v27.4.59-test-a0.0.8) (2025-02-10)
## [v27.4.59-test-a0.0.7](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.6...v27.4.59-test-a0.0.7) (2025-02-10)
## [v27.4.59-test-a0.0.6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.5...v27.4.59-test-a0.0.6) (2025-02-08)
## [v27.4.59-test-a0.0.5](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.4...v27.4.59-test-a0.0.5) (2025-02-07)
## [v27.4.59-test-a0.0.4](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.3...v27.4.59-test-a0.0.4) (2025-02-07)
## [v27.4.59-test-a0.0.3](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.2...v27.4.59-test-a0.0.3) (2025-02-06)
## [v27.4.59-test-a0.0.2](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.1...v27.4.59-test-a0.0.2) (2025-02-05)
## [v27.4.59-test-a0.0.1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59-test-a0.0.0...v27.4.59-test-a0.0.1) (2025-02-05)
### Bug Fixes
* **ghci:** ghci works now as expected ([c3117db](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/c3117dbdcd1de9ef9f0751afa45018e2ebce2c42))
## [v27.4.59-test-a0.0.0](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive//compare/v27.4.59...v27.4.59-test-a0.0.0) (2024-10-25)
### Features
@ -23,97 +75,6 @@ All notable changes to this project will be documented in this file. See [standa
* **util script:** Util script for renaming of files added. ([caf8fec](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/caf8fec5acb94df16293bf9aa0cdab766f8829e8))
* **frontend:** load icons from svg files ([22781e1](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/22781e1565e890cf6c5b40973146b0334cb667aa))
### Bug Fixes
* **stack.yaml:** move to uniworx.de gitlab ([55484e6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/55484e631b786ea3710d322282019baf5292c243))
* **utils/renamer:** Mehr outputs nur im verbose-Fall. ([ac30cb9](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/ac30cb9e6712d0ee3f204da4863d1e2509af8a76))
* **utils:** Verboseparameter -v hinzugefuegt; rekursives makedir; genauere Meldungen. ([1806d9f](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/1806d9f01fc4a0746d2f9df42ef1ee6827c7fa09))
* **Dockerfile:** change rights of source dir to env user ([e7a8183](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/e7a8183656ae419cfee2942543045c6fa6a9caa3))
* **Makefile:** add missing dependency on well-known for backend-builds ([a09dc59](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/a09dc59f260843f8815c382576bb5254d21104bf))
* **frontend:** fixed icon colour in table headers ([4c4571d](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/4c4571d2d0879e89f2572eba6015d34a7f4794c8))
* **doc:** minor haddock problems ([d4f8a6c](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/d4f8a6c77b2a4a4540935f7f0beca0d0605508c8))
## [27.4.76](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.75...v27.4.76) (2024-08-08)
### Bug Fixes
* **ap:** disambiguate action message ([8b0466e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8b0466e74e36e1d0d07518fd317d46b00ab53eff))
* **avs:** fix [#173](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/173) by not using firm superior email as display email ([43f5c5f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/43f5c5f4854d1ab2af27b479e72a58e2818a5696))
* **avs:** towards [#117](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/117) update if current value is Nothing even if oldval == newval ([d1fa01f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d1fa01fcc5125c4adee8849f9c944884926f78ad))
* **avs:** using firm superior as UserEmail is a no-go due to uniqueness constraints ([507a7e0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/507a7e02fc68476d01031dc9f9ee1a669a453ed1))
* **build:** linter likes it ([f929e03](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f929e03129378e08c8a08ed4bd6f8e8716401813))
* **course:** fix [#150](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/150) course edit for associated qualifications requires school admin or lecturer rights ([5b6e4e6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5b6e4e60e7d2957fbce93ee2e2d6d3464b4e3db7))
* **course:** fix [#148](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/148) course qualification ordering ([cfd2534](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/cfd25348ad3b63ac6bc5031467a3c4ead2e07eed)), closes [#150](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/150)
* **course:** fix [#149](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/149) course cloning proposes associated qualifications ([e141976](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e1419766f3a06f702abad0ea42f6552305504ba0))
* **course:** fix [#150](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/150) no longer allow duplicated associated qualifications and orders due to editing existing ([ec02767](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ec027675525b30198378745ed281f60a42471807))
* **course:** WIP course cloning should propose same associated qualifications, towards [#149](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/149) ([bc47387](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/bc47387c91dda60a2f12e52dba28ea7b079316f0))
* **lms:** max e-learning tries default removed and info added to lms overview ([11fdcf0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/11fdcf0d445b8cfe97c3a3c26513a9229937c536))
* **user:** format userDisplayNames having umlaut substitutes with respect to userSurname correctly ([e35a5e9](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e35a5e99a6cea0976fd1c28f919e7d0ac0338503))
## [27.4.75](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.74...v27.4.75) (2024-07-12)
### Bug Fixes
* **build:** make linter happy again ([c17c18f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c17c18f9247ef322bc051602a3cb4a52cd50affa))
* **build:** minor ([ab28c8c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ab28c8c2437680023d80e6ab43113d4328b3a151))
* **firm:** fix [#157](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/157) by removing redundant duplicated code in firm user and supervision handling ([28e2739](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/28e2739e515700d15c75647c0efe2fe9a9cf15b1))
* **job:** change some queueJob' to queueJob instead ([fa0541a](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/fa0541aa4eaf10f98535a0959593b148b8346109))
* **lms:** allow 2nd reminders to be independent of renewal period ([d853e85](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d853e8559b753865ee818bf24764f5c8d2e2303f))
* **lms:** move lms reuse info from QualificationR to LmsR ([468af9d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/468af9de9da44a8ad685ca4bb6890a3e630b58be))
* **lms:** send second reminder indepentently from renewal period ([a97c3a5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a97c3a5c9d3cb9dddf90f561712f0845400893bd))
* **nix:** workaround parsing port numbers failed in nix-shell ([b5215cc](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b5215cc7e8df3a7ad636271c8e6950979b2b8e42))
* **users:** nameHtml no longer complains about differing case for surname and displayname ([a1668f8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/a1668f891a36b887439afb098f016ef22535af42))
* **users:** remove users with company post address from list of unreachable users ([c813c66](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c813c665ed306135b7813d91d23310341c689f41))
## [27.4.74](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.73...v27.4.74) (2024-07-04)
### Bug Fixes
* **lms:** fix [#161](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/161) lms for multiple joint qualifications ([f869a82](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f869a829d2c1a726930864b3af62d1f0fbebe955))
## [27.4.73](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.72...v27.4.73) (2024-07-03)
### Bug Fixes
* **letter:** rephrase some minor letter parts ([0ac75e0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/0ac75e0d5948cb90855d0e36ca8e99c22a0f6fcb))
## [27.4.72](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.71...v27.4.72) (2024-07-02)
### Bug Fixes
* **avs:** do not associate users by AvsInfoPersonEmail ([9e2f221](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/9e2f2214ce5c7ee1e8d80e6fa75298b7a70d9043))
* **avs:** fix superfluous quotes for matriculation numbers on newly created users ([ff9014c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/ff9014ce05d197c1dc0fce0774a640789cb38b26))
* **avs:** towards [#169](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/169) - superiors are elevated to max priority for that company ([5bf8539](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5bf85394d4db6de8f10b4e318d667130d37601ac))
* **firm:** supervisor secondary did not work as intended ([d4f3ce7](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d4f3ce7bf3d208b16f95ab81971b47dfa752939a))
## [27.4.71](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.70...v27.4.71) (2024-06-27)
### Bug Fixes
* **avs:** company superior emails become company wide supervisors ([37efc89](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/37efc89e0723452e6d271ba5b43d6bd026642190))
* **avs:** match mobile number better between LDAP and AVS ([f108c6c](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f108c6cfec2d94d866e7c1605b0abe5471fd0f2b))
* **avs:** new AVS from existing LDAP user no longer misses fields ([2559346](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2559346d963ede802321dfc8cbd2088d9a5de685))
* **avs:** priority for picking primary email demote superior ([e4fa1dd](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/e4fa1ddd6873910bef82d569fe16aca936efc567))
* **build:** add missing license file ([8721bdb](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/8721bdb3f349658baab144d64c19942bfd7fa49a))
* **build:** hlint wants a newtype instead ([18cdc52](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/18cdc52df094b9dbccd4f015561367cea59e33fe))
* **doc:** fix erroneous unintentional haddock annotations ([3dfc7f8](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/3dfc7f8c8b12dd6ef87848a75f1669d700fffe4c))
* **i18n:** add missing translation for new primary company ([c212f2e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c212f2e8d735616e59c9b8111a34118e3a48fd47))
* **i18n:** add missing translation for new primary company ([2cc529b](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/2cc529be39655c317ca028f8f09fa80826ec668d))
* **ldap:** match mobile number better between LDAP and AVS ([47e5628](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/47e56280fce4ad37e6bc3b9f1c61cb7867069cc5))
* **letter:** adjust spacing, pin location and interpolation ([d4a0e1f](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/d4a0e1f201151f76e8e9afd67b456cc878d2afde))
* **letter:** convenience links working again ([5f1af13](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5f1af130edae7ada2f0c7f7829890bbe0d4f395a))
* **letter:** expiry and valid dates were wrong ([f8c3663](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/f8c36636ff1f2591507e993af32ed01af94cf1fc))
* **letter:** switch markdown for renewal letter too ([c38e87e](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/c38e87e1e0e9285a10c00521b7440cd8246af88a))
* **print:** fix [#167](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/167) by sotring affected user in PrintJob ([73aecc2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/73aecc2df833bdeed93a113b6c756e36b50491b7))
## [27.4.70](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v27.4.69...v27.4.70) (2024-06-21)
### Bug Fixes
* **stack.yaml:** move to uniworx.de gitlab ([55484e6](https://fraport@dev.azure.com/fraport/Fahrerausbildung/_git/FRADrive/commit/55484e631b786ea3710d322282019baf5292c243))

467
Makefile
View File

@ -1,87 +1,57 @@
export SHELL=bash
# MAKE=make -f Makefile-loggingsymbols
# MAKE=make -d
export CLEAN_DEPENDENCIES ?= false
export CLEAN_IMAGES ?= false
# System information
export CPU_CORES = $(shell cat /proc/cpuinfo | grep '^processor' | wc -l)
export CONTAINER_COMMAND ?= podman
export CONTAINER_BGRUN ?= $(CONTAINER_COMMAND) run -dit --network=host --replace
export CONTAINER_FGRUN ?= $(CONTAINER_COMMAND) run -it --network=host --replace
export IMAGE_REGISTRY = docker.io
export MEMCACHED_IMAGE = $(IMAGE_REGISTRY)/memcached:latest
export MINIO_IMAGE = $(IMAGE_REGISTRY)/minio/minio:latest
export MAILDEV_IMAGE = $(IMAGE_REGISTRY)/maildev/maildev:latest # TODO: needs different port than 1025 to avoid conflicts
export IN_CONTAINER ?= false
export IN_CI ?= false
export CONTAINER_FILE
export CONTAINER_IDENT
export CF_PREFIX
export DEVELOP
export MOUNT_DIR=/mnt/fradrive
export CONTAINER_ATTACHED
export CONTAINER_INIT
export CONTAINER_CLEANUP
export SERVICE
export SERVICE_VARIANT ?= $(SERVICE)
export JOB
export CONTAINER_CMD
export SET_CONTAINER_CMD
export ENTRYPOINT
export EXEC_OPTS
export STACK_CORES = $(shell echo $(($(CPU_CORES)/2)))
export BASE_PORTS
export UNIWORXDB_OPTS ?= -cf
export PROD ?= false
export ENTRYPOINT ?= bash
export SRC
ifneq ($(PROD),true)
export --DEVELOPMENT=--flag uniworx:dev
endif
export DATE := $(shell date +'%Y-%m-%dT%H-%M-%S')
export CURR_DEV = $(shell cat develop/.current 2>/dev/null)
export SET_DEVELOP = $(eval DEVELOP=develop/$$(CURR_DEV))
export NEW_DEVELOP = $(eval DEVELOP=develop/$$(DATE))
.PHONY: help
# HELP: print out this help message
help:
@if [ -z "$$(which perl 2>/dev/null)" ] ; then \
$(CONTAINER_FGRUN) .:/mnt 'debian:12.5' '/mnt/utils/makehelp.pl' '/mnt/Makefile' ; \
else \
utils/makehelp.pl Makefile ; \
fi
docker compose run help
.PHONY: clean
# HELP: stop all running containers and remove all compilation results in the directory (but leave images including dependencies unharmed)
# HELP: clean compilation caches
clean:
rm -rf develop
-rm -rf node_modules .npm .cache assets/icons assets/favicons static well-known config/manifest.json
-rm -rf .stack-work .stack-work.lock
-rm -rf bin .Dockerfile develop
-$(CONTAINER_COMMAND) container prune --force
.PHONY: clean-images
# HELP: stop all running containers and clean all images from local repositories
clean-images:
rm -rf develop
sleep 5
-$(CONTAINER_COMMAND) system prune --all --force --volumes
-$(CONTAINER_COMMAND) image prune --all --force
-$(CONTAINER_COMMAND) volume prune --force
$(MAKE) clean-frontend CLEAN_DEPENDENCIES=$(CLEAN_DEPENDENCIES) CLEAN_IMAGES=$(CLEAN_IMAGES)
$(MAKE) clean-backend CLEAN_DEPENDENCIES=$(CLEAN_DEPENDENCIES) CLEAN_IMAGES=$(CLEAN_IMAGES)
.PHONY: clean-all
# HELP: like clean but with full container, image, and volume prune
clean-all: clean-images
-rm -rf .stack
# HELP: clean everything, including dependency and image caches
clean-all: CLEAN_DEPENDENCIES = true
clean-all: CLEAN_IMAGES = true
clean-all: clean ;
.PHONY: clean-%
# HELP(clean-$SERVICE): invalidate caches for a given service. Supported services: frontend, backend.
clean-%:
$(MAKE) stop-$*
@$(MAKE) -- --clean-$*
@echo "Cleaned $* build files and binaries."
ifeq ("$(CLEAN_DEPENDENCIES)", "true")
@$(MAKE) -- --clean-$*-deps
@echo "Cleaned $* dependencies."
endif
ifeq ("$(CLEAN_IMAGES)", "true")
$(MAKE) kill-$*
docker compose rm --force --volumes
docker compose down --rmi 'all' --volumes
@echo "Cleaned $* image."
endif
--clean-frontend:
-rm -rf assets/icons assets/favicons
-rm -rf static well-known
--clean-frontend-deps:
-rm -rf frontend/node_modules
-rm -rf frontend/.npm
--clean-backend:
-rm -rf backend/.stack-work
-rm -rf bin/
--clean-backend-deps:
-rf -rf backend/.stack
# TODO: only release when build and tests are passing!!!
.PHONY: release
# HELP: create, commit and push a new release
release:
@ -93,328 +63,61 @@ release:
git push origin $${VERSION}
.PHONY: compile
compile:
$(MAKE) compile-frontend
$(MAKE) compile-backend
# HELP: perform full compilation (frontend and backend)
compile: compile-frontend compile-backend ;
.PHONY: compile-%
# HELP(compile-$SERVICE): compile a given service once
compile-%:
docker compose run --remove-orphans --build --no-deps $* make compile
.PHONY: start
start:
$(MAKE) start-postgres
$(MAKE) start-memcached
$(MAKE) start-minio
$(MAKE) compile-frontend
$(MAKE) compile-uniworxdb
$(MAKE) start-backend
.PHONY: %-backend
%-backend: SERVICE=backend
%-backend: SERVICE_VARIANT=backend
%-backend: CONTAINER_CMD=localhost/fradrive/backend
%-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443"
.PHONY: %-uniworxdb
%-uniworxdb: SERVICE=backend
%-uniworxdb: SERVICE_VARIANT=uniworxdb
%-uniworxdb: CONTAINER_CMD=localhost/fradrive/backend
.PHONY: %-ghci
%-ghci: SERVICE=backend
%-ghci: SERVICE_VARIANT=ghci
%-ghci: CONTAINER_CMD=localhost/fradrive/backend
.PHONY: %-hoogle
%-hoogle: SERVICE=backend
%-hoogle: SERVICE_VARIANT=hoogle
%-hoogle: BASE_PORTS = "HOOGLE_PORT=8081"
%-hoogle: CONTAINER_CMD=localhost/fradrive/backend
--start-hoogle:
HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \
stack $(STACK_CORES) hoogle -- server --local --port $${HOOGLE_PORT}
.PHONY: %-frontend
%-frontend: SERVICE=frontend
%-frontend: SERVICE_VARIANT=frontend
%-frontend: CONTAINER_CMD=localhost/fradrive/frontend
.PHONY: %-postgres
%-postgres: SERVICE=postgres
%-postgres: SERVICE_VARIANT=postgres
%-postgres: BASE_PORTS = "PGPORT=5432"
%-postgres: CONTAINER_CMD=localhost/fradrive/postgres
.PHONY: %-memcached
%-memcached: SERVICE=memcached
%-memcached: SERVICE_VARIANT=memcached
%-memcached: SET_CONTAINER_CMD=$$(MEMCACHED_IMAGE) --port=`cat $$(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'`
%-memcached: BASE_PORTS = "MEMCACHED_PORT=11211"
.PHONY: %-minio
%-minio: SERVICE=minio
%-minio: SERVICE_VARIANT=minio
%-minio: SET_CONTAINER_CMD=$$(MINIO_IMAGE) -- server `mktemp` --address=:`cat $$(CONTAINER_FILE) | grep 'UPLOAD_S3_PORT=' | sed 's/UPLOAD_S3_PORT=//'`
%-minio: BASE_PORTS = "UPLOAD_S3_PORT=9000"
# HELP: start complete development environment with a fresh test database
start: start-postgres start-maildev start-memcached start-minio start-backend
docker compose exec backend make start
.PHONY: start-%
start-%: JOB=start
start-%: CF_PREFIX = start-
start-%: CONTAINER_ATTACHED = false
start-%: --act ;
.PHONY: compile-%
compile-%: JOB=compile
compile-%: CF_PREFIX = compile-
compile-%: CONTAINER_ATTACHED = true
compile-%: --act ;
.PHONY: dependencies-%
dependencies-%: JOB=dependencies
dependencies-%: CF_PREFIX = dependencies-
dependencies-%: CONTAINER_ATTACHED = true
dependencies-%: --act ;
.PHONY: test-%
test-%: JOB=test
test-%: CF_PREFIX = test-
test-%: CONTAINER_ATTACHED = true
test-%: --act ;
.PHONY: lint-%
lint-%: JOB=lint
lint-%: CF_PREFIX = lint-
lint-%: CONTAINER_ATTACHED = true
lint-%: --act ;
# HELP(start-$SERVICE): start a given service
start-%:
docker compose up -d --build $*
.PHONY: shell-%
# HELP(shell-$SERVICE): launch (bash) shell inside a new $SERVICE container
shell-%: JOB=shell
shell-%: CF_PREFIX=shell-
shell-%: CONTAINER_ATTACHED=true
shell-%: --act ;
# HELP(shell-$SERVICE): launch a (bash) shell inside a given service
shell-%:
docker compose run --build --no-deps --entrypoint="$(ENTRYPOINT)" $*
.PHONY: ghci
# HELP(ghci): launch new backend instance and enter interactive ghci shell
ghci: shell-ghci;
--act: --develop_containerized;
--develop_%: PORTS = $(foreach PORT,$(BASE_PORTS),$(shell utils/next_free_port.pl $(PORT)))
--develop_%: --ensure-develop
DEVELOP=develop/`cat develop/.current` ; \
CONTAINER_IDENT=$(CF_PREFIX)$(SERVICE_VARIANT) ; \
CONTAINER_FILE=$${DEVELOP}/$${CONTAINER_IDENT} ; \
if [[ -e $${CONTAINER_FILE} ]]; then \
>&2 echo "Another $* service is already running! Use \"make new-develop\" to start a new develop instance despite currently running services." ; \
exit 1 ; \
fi ; \
echo "$(PORTS)" | sed 's/ /\n/g' > $${CONTAINER_FILE} ; \
$(MAKE) -- --$* CONTAINER_FILE=$${CONTAINER_FILE} CONTAINER_IDENT=$${CONTAINER_IDENT} JOB=$(JOB)
.PHONY: rebuild-%
# HELP(rebuild-{backend,frontend,database,memcached,minio}): force-rebuild a given container image
rebuild-%:
$(MAKE) -- --image-build SERVICE=$* NO_CACHE=--no-cache
--image-build:
ifeq "$(CONTAINER_CMD)" "localhost/fradrive/$(SERVICE)"
rm -f .Dockerfile
ln -s docker/$(SERVICE)/Dockerfile .Dockerfile
MOUNT_DIR=/mnt/fradrive; \
PROJECT_DIR=/mnt/fradrive; \
if [ "$(IN_CI)" == "true" ] ; then \
PROJECT_DIR=/fradrive; \
fi; \
if [ "$(IN_CONTAINER)" == "false" ] ; then \
$(CONTAINER_COMMAND) build $(NO_CACHE) \
-v $(PWD):$${MOUNT_DIR} \
--build-arg MOUNT_DIR=$(MOUNT_DIR) \
--build-arg PROJECT_DIR=$${PROJECT_DIR} \
--env IN_CONTAINER=true \
--env JOB=$(JOB) \
--tag fradrive/$(SERVICE) \
--file $(PWD)/.Dockerfile ; \
fi
else
:
endif
--containerized: --image-build
DEVELOP=`cat develop/.current` ; \
./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" "$(CONTAINER_INIT)" "$(CONTAINER_CLEANUP)" & \
CONTAINER_NAME=fradrive.$(CURR_DEV).$(CONTAINER_IDENT) ; \
if ! [ -z "$(SET_CONTAINER_CMD)" ] ; \
then \
CONTAINER_CMD="$(SET_CONTAINER_CMD)" ; \
else \
CONTAINER_CMD=$(CONTAINER_CMD) ; \
fi ; \
CONTAINER_ID=`$(CONTAINER_BGRUN) \
-v $(PWD):$(MOUNT_DIR) \
--env IN_CONTAINER=true \
--env FRADRIVE_MAKE_TARGET="--$(JOB)-$(SERVICE_VARIANT)" \
--env CONTAINER_FILE=$(CONTAINER_FILE) \
--env CONTAINER_NAME=$${CONTAINER_NAME} \
--env JOB=$(JOB) \
--env SRC=$(SRC) \
--name $${CONTAINER_NAME} \
$${CONTAINER_CMD} \
` ; \
printf "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)" ; \
if [[ "true" == "$(CONTAINER_ATTACHED)" ]] ; then \
$(CONTAINER_COMMAND) attach $${CONTAINER_ID} || : ; \
fi
# For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J
# HELP(start-backend): start development instance
--start-backend:
export YESOD_IP_FROM_HEADER=true; \
export DEV_PORT_HTTP=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTP=' | sed 's/DEV_PORT_HTTP=//'`; \
export DEV_PORT_HTTPS=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTPS=' | sed 's/DEV_PORT_HTTPS=//'`; \
export HOST=127.0.0.1 ; \
export PORT=$${PORT:-$${DEV_PORT_HTTP}} ; \
export DETAILED_LOGGING=$${DETAILED_LOGGING:-true} ; \
export LOG_ALL=$${LOG_ALL:-false} ; \
export LOGLEVEL=$${LOGLEVEL:-info} ; \
export DUMMY_LOGIN=$${DUMMY_LOGIN:-true} ; \
export SERVER_SESSION_ACID_FALLBACK=$${SERVER_SESSION_ACID_FALLBACK:-true} ; \
export SERVER_SESSION_COOKIES_SECURE=$${SERVER_SESSION_COOKIES_SECURE:-false} ; \
export COOKIES_SECURE=$${COOKIES_SECURE:-false} ; \
export ALLOW_DEPRECATED=$${ALLOW_DEPRECATED:-true} ; \
export ENCRYPT_ERRORS=$${ENCRYPT_ERRORS:-false} ; \
export RIBBON=$${RIBBON:-$${HOST:-localhost}} ; \
export APPROOT=$${APPROOT:-http://localhost:$${DEV_PORT_HTTP}} ; \
export AVSPASS=$${AVSPASS:-nopasswordset} ; \
stack $(STACK_CORES) exec --local-bin-path $$(pwd)/bin --copy-bins -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}"
# HELP(compile-backend): compile backend binaries
--compile-backend:
stack build $(STACK_CORES) --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin --copy-bins
# HELP(dependencies-backend): (re-)build backend dependencies
--dependencies-backend: uniworx.cabal
stack build $(STACK_CORES) --fast --only-dependencies
# HELP(lint-backend): lint backend
--lint-backend:
stack build $(STACK_CORES) --test --fast --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint
# HELP(test-backend): test backend
--test-backend:
stack build $(STACK_CORES) --test --coverage --fast --flag uniworx:library-only $(--DEVELOPMENT)
uniworx.cabal:
stack exec -- hpack --force
# HELP(compile-frontend): compile frontend assets
--compile-frontend: node_modules assets esbuild.config.mjs
npm run build
--start-frontend: --compile-frontend;
--dependencies-frontend: node_modules assets static well-known;
node_modules: package.json package-lock.json
npm install --cache .npm --prefer-offline
package-lock.json: package.json
npm install --cache .npm --prefer-offline
assets: assets/favicons assets/icons;
assets/favicons:
./utils/faviconize.pl assets/favicon.svg long assets/favicons
assets/icons: node_modules assets/icons-src/fontawesome.json
./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/solid assets/icons-src/fontawesome.json assets/icons/fradrive
./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/regular assets/icons-src/fontawesome.json assets/icons/fradrive
-cp assets/icons-src/*.svg assets/icons/fradrive
static: node_modules assets esbuild.config.mjs
npm run build
well-known: static;
# HELP(compile-uniworxdb): clear and fill database. requires running postgres instance (use "make start-postgres" to start one)
# TODO (db-m-$MIGRATION-backend): apply migration (see src/Model/Migration/Definition.hs for list of available migrations)
--compile-uniworxdb: --compile-backend
SERVER_SESSION_ACID_FALLBACK=${SERVER_SESSION_ACID_FALLBACK:-true} ; \
AVSPASS=${AVSPASS:-nopasswordset} ; \
./bin/uniworxdb $(UNIWORXDB_OPTS)
--shell-ghci:
stack ghci -- $(SRC)
# --main-is uniworx:exe:uniworx
# HELP(shell-{backend,frontend,memcached,minio,postgres}): enter (bash) shell inside a new container of a given service
--shell-%:
/bin/bash
# HELP(start-minio): start minio service
.PHONY: status
# HELP: print develop status: running containers, used ports
status:
@./utils/develop-status.pl -a
.PHONY: log-%
# HELP(log-$(JOB)-$(SERVICE)): inspect output of a given service. The service must be currently running When a service supports multiple running instances in one develop (i.e. backend), you need to specify the exact instance by its associated file (e.g. backend-1, backend-2, etc.), please check the contents of the develop/ directory for a list of running instances.
log-%:
DEVELOP=develop/`cat develop/.current` ; \
SEARCH_FILE="$${DEVELOP}/$*" ; \
if [[ ! -e "$${SEARCH_FILE}" ]] ; then \
SEARCH_FILE="$${DEVELOP}/.exited.$*" ; \
fi ; \
if [[ -e "$${SEARCH_FILE}" ]] ; then \
$(CONTAINER_COMMAND) logs --follow `cat "$${SEARCH_FILE}" | grep CONTAINER_ID= | sed 's/^CONTAINER_ID=//'` ; \
else \
>&2 echo "Cannot show log: No develop file found for '$*'" ; \
exit 1 ; \
fi
.PHONY: enter
# HELP: launch (bash) shell inside a currently running container. Use ./enter shell wrapper for more convenient usage, possibly with tab-completion in the future
enter: --ensure-develop
$(MAKE) -- --enter
.PHONY: psql
# HELP: enter psql (postgresql) cli inside a currently running database container
psql: ENTRYPOINT=/usr/bin/psql -d uniworx
psql: EXEC_OPTS=--user postgres
psql: --ensure-develop
$(MAKE) -- --enter CONTAINER_FILE=develop/`cat develop/.current`/start-postgres
--enter:
CONTAINER_ID=`cat $(CONTAINER_FILE) | grep 'CONTAINER_ID=' | sed 's/CONTAINER_ID=//'` ; \
$(CONTAINER_COMMAND) exec -it $(EXEC_OPTS) $${CONTAINER_ID} $(if $(ENTRYPOINT),$(ENTRYPOINT),/bin/bash)
# HELP: launch ghci instance. Use in combination with SRC to specify the modules to be loaded by ghci: make ghci SRC=src/SomeModule.hs
ghci: ENTRYPOINT=stack ghci $(SRC)
ghci: shell-backend ;
.PHONY: stop
# HELP: stop all currently running develop instances
# HELP: stop all services
stop:
rm -rf develop
docker compose down
.PHONY: stop-%
# HELP(stop-SERVICE): stop all currently running develop instances of a given service (i.e. backend,frontend,uniworxdb,hoogle,postgres,...)
# HELP(stop-JOB): stop all currently running develop instances of a given job (i.e. compile,start,test,lint)
stop-compile: CF_PREFIX=compile-
stop-start: CF_PREFIX=start-
stop-test: CF_PREFIX=test-
stop-lint: CF_PREFIX=lint-
stop-%: --stop;
--stop:
$(SET_DEVELOP)
ifdef CF_PREFIX
rm -rf $(DEVELOP)/$(CF_PREFIX)*
endif
ifdef SERVICE_VARIANT
rm -rf $(DEVELOP)/*-$(SERVICE_VARIANT)
endif
# HELP(stop-$SERVICE): stop a given service
stop-%:
docker compose down $*
.PHONY: kill-%
# HELP(kill-$SERVICE): kill a given service the hard way. Use this if the servive does not respond to stop.
kill-%:
docker compose kill $*
.PHONY: new-develop
# HELP: instantiate new development bundle, i.e. create new directory under develop/
new-develop:
$(NEW_DEVELOP)
mkdir -p $(DEVELOP)
$(MAKE) develop/.current
.PHONY: switch-develop
# HELP: switch current develop instance to DEVELOP=...
switch-develop:
if ! [ -e develop/$(DEVELOP) ]; then \
echo "Specified develop $(DEVELOP) does not exist! Not switching." ; \
exit 1 ; \
fi ; \
echo "$(DEVELOP)" > develop/.current
--ensure-develop:
if ! [[ -e develop ]]; then \
$(MAKE) new-develop; \
fi
$(MAKE) develop/.current
$(SET_DEVELOP)
.PHONY: develop/.current
develop/.current:
ls -1 develop | tail -n1 > develop/.current
.PHONY: status
# HELP: print an overview of currently running services and their health
status:
docker compose ps
.PHONY: top
# HELP: print an overview of the ressource usage of the currently running services
top:
docker compose stats
.PHONY: list-projects
# HELP: list all currently running projects on this machine
list-projects:
docker compose ls
.PHONY: log-%
# HELP(log-$SERVICE): follow the output of a given service. Service must be running.
log-%:
docker compose logs --follow --timestamps $*
.PHONY: --%
.SUFFIXES: # Delete all default suffixes

254
azure-pipelines.yaml Normal file → Executable file
View File

@ -1,67 +1,197 @@
# SPDX-FileCopyrightText: 2024 Sarah Vaupel <sarah.vaupel@uniworx.de>
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
trigger:
branches:
include:
- '*'
tags:
include:
- '*'
#paths:
# exclude:
# - CHANGELOG.md
parameters:
- name: services
type: object
default:
- name: frontend
imageBase:
image: devfra.azurecr.io/de.fraport.build/npm
tag: node-20
# extraBuildOptions: |
# --build-arg NPM_CUSTOM_REGISTRY=https://pkgs.dev.azure.com/fraport/_packaging/packages/npm/registry/
dependsOn: []
dependenciesCaches:
- key: package.json | package-lock.json
path: node_modules/
- key: package.json | package-lock.json
path: .npm/
- key: package.json | esbuild.config.mjs | utils/renamer.pl | utils/faviconize.pl | frontend/src/icons.scss
path: assets/icons/
- key: package.json | esbuild.config.mjs | utils/renamer.pl | utils/faviconize.pl | frontend/src/icons.scss
path: assets/favicons/
buildPool: 'Prod Private Agent Pool'
buildCores: 1
buildTimeout: 60
buildArtifacts: |
assets/icons/fradrive/*.svg
assets/favicons/*.png
assets/favicons/include.html
frontend/src/env.sass
config/manifest.json
static/**/*
well-known/**/*
- name: backend
imageBase:
image: devfra.azurecr.io/de.fraport.build/haskell
tag: 8.10.4
dependsOn:
- Build_frontend
dependenciesCaches:
- key: stack.yaml | stack.yaml.lock
path: .stack/
buildPool: 'Prod Private Agent Pool DS3'
buildCores: 3
buildTimeout: 1440
buildArtifacts: |
bin/*
variables:
buildImageUpstream: devfra.azurecr.io/de.fraport.fradrive.build
setupImages: $[ or( eq(variables.forcePushLatest, true), eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/heads/update'), startsWith(variables['Build.SourceBranch'], 'refs/tags/') ) ]
pool: 'Prod Private Agent Pool'
jobs:
# - job: HelloWorld
# container:
# image: 'devfra.azurecr.io/de.fraport.trusted/ubuntu:22.04'
# endpoint: devfra
# steps:
# - script: echo Hello, world!
# displayName: 'Run a one-line script'
# - script: |
# echo Add other tasks to build, test, and deploy your project.
# echo See https://aka.ms/yaml
# displayName: 'Run a multi-line script'
- job: DockerTaskTest
container:
image: devfra.azurecr.io/de.fraport.build/tools:1.1.0
endpoint: devfra
steps:
- task: Docker@2
name: dockerLoginDevFra
displayName: Docker Login to devfra
inputs:
command: login
containerRegistry: devFra
- task: Docker@2
name: dockerBuild
displayName: Backend image build test
inputs:
command: build
Dockerfile: docker/backend/Dockerfile
buildContext: .
tags: |
$(Build.BuildNumber)
backend
arguments: |
--build-arg HTTPS_PROXY=http://proxy.frankfurt-airport.de:8080
--build-arg HTTP_PROXY=http://proxy.frankfurt-airport.de:8080
--build-arg NO_PROXY='localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io'
--build-arg PROJECT_DIR=/fradrive
--build-arg MOUNT_DIR=/mnt/fradrive
# - job: BuildKitTest
# container:
# image: 'devfra.azurecr.io/de.fraport.trusted/buildkit:0.12.1'
# endpoint: devfra
# steps:
# - script: buildctl build \
# --frontend=dockerfile.v0 \
# --local context=. \
# --local dockerfile=docker/backend/Dockerfile
# displayName: BuildKit test
# - job: CustomBuildahTest
# container:
# image: 'devfra.azurecr.io/de.fraport.trusted/ubuntu:22.04'
# endpoint: devfra
# steps:
# - script: |
# id
# docker build --help
# sudo apt-get -y update
# sudo apt-get -y install buildah
# buildah bud -t fradrive-backend-test --volume .:/mnt/fradrive --file docker/backend/Dockerfile
# displayName: Build buildah image
stages:
- stage: Setup
jobs:
- ${{ each service in parameters.services }}:
- template: .azure-pipelines/templates/jobs/setup_image.yaml
parameters:
imageName: ${{service.name}}
imageBase: ${{service.imageBase}}
- template: .azure-pipelines/templates/jobs/setup_dependencies.yaml
parameters:
serviceName: ${{service.name}}
dependenciesCaches: ${{service.dependenciesCaches}}
dependenciesBuildPool: ${{service.buildPool}}
dependenciesBuildCores: ${{service.buildCores}}
dependenciesBuildTimeout: ${{service.buildTimeout}}
- stage: Build
dependsOn: Setup
jobs:
- ${{ each service in parameters.services }}:
- job: Build_${{service.name}}
displayName: Compile ${{service.name}}
dependsOn: ${{service.dependsOn}}
pool: '${{service.buildPool}}'
timeoutInMinutes: ${{service.buildTimeout}}
container:
${{ if eq(variables.setupImages, true) }}:
image: $(buildImageUpstream)/${{service.name}}:$(Build.BuildNumber)
${{ else }}:
image: $(buildImageUpstream)/${{service.name}}:latest
endpoint: devfra
env:
PROJECT_DIR: $(Build.Repository.LocalPath)
IN_CONTAINER: true
IN_CI: true
steps:
- ${{ each dependencyCache in service.dependenciesCaches }}:
- template: .azure-pipelines/templates/steps/cache.yaml
parameters:
cacheIdent: '${{service.name}}-dependencies'
cacheKeys: '${{dependencyCache.key}}'
cachePath: '${{dependencyCache.path}}'
- ${{ each dependency in service.dependsOn }}:
- template: .azure-pipelines/templates/steps/artifact-download.yaml
parameters:
artifactName: '${{dependency}}'
- template: .azure-pipelines/templates/steps/make.yaml
parameters:
makeJob: compile
makeService: ${{service.name}}
makeVars: 'CPU_CORES=${{service.buildCores}} STACK_CORES=-j${{service.buildCores}}'
- task: CopyFiles@2
displayName: Prepare ${{service.name}} build artifacts for upload
inputs:
Contents: '${{service.buildArtifacts}}'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: Publish ${{service.name}} build artifacts
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'Build_${{service.name}}'
publishLocation: 'Container'
# - stage: Test
# dependsOn: Build
# condition: eq(variables.skipTests, false)
# jobs:
# - ${{ each service in parameters.services }}:
# - job: Test_${{service.name}}
# displayName: Run ${{service.name}} tests
# pool: '${{service.buildPool}}'
# timeoutInMinutes: ${{service.buildTimeout}}
# container:
# # TODO: do not use latest on update branches
# image: $(buildImageUpstream)/${{service.name}}:latest
# endpoint: devfra
# env:
# PROJECT_DIR: $(Build.Repository.LocalPath)
# IN_CONTAINER: true
# IN_CI: true
# steps:
# - ${{ each dependencyCache in service.dependenciesCaches }}:
# - template: .azure-pipelines/templates/steps/cache.yaml
# parameters:
# cacheIdent: '${{service.name}}-dependencies'
# cacheKeys: '${{dependencyCache.key}}'
# cachePath: '${{dependencyCache.path}}'
# - ${{ each dependency in service.dependsOn }}:
# - template: .azure-pipelines/templates/steps/artifact-download.yaml
# parameters:
# artifactName: '${{dependency}}'
# - task: Docker@2
# displayName: Login to container registry
# inputs:
# command: login
# containerRegistry: devfra
# - task: Bash@3
# displayName: Start database container for testing
# inputs:
# targetType: inline
# script: |
# docker run -d devfra.azurecr.io/de.fraport.trusted/postgres:16.1-bookworm
# - template: .azure-pipelines/templates/steps/make.yaml
# parameters:
# makeJob: lint
# makeService: ${{service.name}}
# makeVars: 'CPU_CORES=${{service.buildCores}} STACK_CORES=-j${{service.buildCores}}'
# - template: .azure-pipelines/templates/steps/make.yaml
# parameters:
# makeJob: test
# makeService: ${{service.name}}
# makeVars: 'CPU_CORES=${{service.buildCores}} STACK_CORES=-j${{service.buildCores}}'
# - task: Docker@2
# displayName: Logout from container registry
# inputs:
# command: logout
# containerRegistry: devfra
# - job: TestReport_${{service.name}}
# displayName: Upload test reports for ${{service.name}}
# steps:
# - script: echo "Work in progress" # TODO
- stage: Release
dependsOn: Build # TODO Test
condition: or(eq(variables.forceRelease, true), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
jobs:
- template: .azure-pipelines/templates/jobs/release.yaml
parameters:
releaseTag: ${{split(variables['Build.SourceBranch'], '/')[2]}}

View File

40
backend/Dockerfile Normal file
View File

@ -0,0 +1,40 @@
ARG FROM_IMG=docker.io/library/debian
ARG FROM_TAG=12.5
FROM ${FROM_IMG}:${FROM_TAG}
ENV LANG=de_DE.UTF-8
# basic dependencies
RUN apt-get -y update && apt-get -y install git
RUN apt-get -y update && apt-get -y install haskell-stack
RUN apt-get -y update && apt-get -y install llvm
RUN apt-get -y update && apt-get install -y --no-install-recommends locales locales-all
# compile-time dependencies
RUN apt-get -y update && apt-get install -y libpq-dev libsodium-dev
RUN apt-get -y update && apt-get -y install g++ libghc-zlib-dev libpq-dev libsodium-dev pkg-config
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
# run-time dependencies for uniworx binary
RUN apt-get -y update && apt-get -y install fonts-roboto
# RUN apt-get -y update && apt-get -y install pdftk
# RUN apt-get -y update && apt-get -y install \
# texlive texlive-latex-recommended texlive-luatex texlive-plain-generic texlive-lang-german texlive-lang-english
RUN apt-get -y update && apt-get -y install texlive
# RUN ls /usr/local/texlive
# RUN chown -hR root /usr/local/texlive/2018
# RUN tlmgr init-usertree
# RUN tlmgr option repository ftp://tug.org/historic/systems/texlive/2018/tlnet-final
# RUN tlmgr update --self --all
ARG PROJECT_DIR=/fradrive
ENV PROJECT_DIR=${PROJECT_DIR}
# RUN mkdir -p "${PROJECT_DIR}"; chmod -R 777 "${PROJECT_DIR}"
WORKDIR ${PROJECT_DIR}
ENV HOME=${PROJECT_DIR}
ENV STACK_ROOT="${PROJECT_DIR}/.stack"
ENV STACK_SRC=""
ENV STACK_ENTRY="ghci ${STACK_SRC}"
ENTRYPOINT stack ${STACK_ENTRY}

51
backend/Makefile Normal file
View File

@ -0,0 +1,51 @@
export CPU_CORES = $(shell cat /proc/cpuinfo | grep '^processor' | wc -l)
export STACK_CORES = $(shell echo $(($(CPU_CORES)/2)))
ifeq ($(PROD),true)
export --DEVELOPMENT=--flag uniworx:-dev
else
export --DEVELOPMENT=--flag uniworx:dev
endif
.PHONY: dependencies
dependencies:
stack install hpack; stack install yesod-bin; \
stack build -j2 --only-dependencies
.PHONY: compile
compile: dependencies
stack build $(STACK_CORES) --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin --copy-bins
.PHONY: lint
lint:
stack build $(STACK_CORES) --test --fast --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint
.PHONY: test
test:
stack build $(STACK_CORES) --test --coverage --fast --flag uniworx:library-only $(--DEVELOPMENT)
# For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J
.PHONY: start
start: dependencies
export YESOD_IP_FROM_HEADER=true; \
export DEV_PORT_HTTP=3000; \
export DEV_PORT_HTTPS=3443; \
export HOST=127.0.0.1 ; \
export PORT=$${PORT:-$${DEV_PORT_HTTP}} ; \
export DETAILED_LOGGING=$${DETAILED_LOGGING:-true} ; \
export LOG_ALL=$${LOG_ALL:-false} ; \
export LOGLEVEL=$${LOGLEVEL:-info} ; \
export DUMMY_LOGIN=$${DUMMY_LOGIN:-true} ; \
export SERVER_SESSION_ACID_FALLBACK=$${SERVER_SESSION_ACID_FALLBACK:-true} ; \
export SERVER_SESSION_COOKIES_SECURE=$${SERVER_SESSION_COOKIES_SECURE:-false} ; \
export COOKIES_SECURE=$${COOKIES_SECURE:-false} ; \
export ALLOW_DEPRECATED=$${ALLOW_DEPRECATED:-true} ; \
export ENCRYPT_ERRORS=$${ENCRYPT_ERRORS:-false} ; \
export RIBBON=$${RIBBON:-$${HOST:-localhost}} ; \
export APPROOT=$${APPROOT:-http://localhost:$${DEV_PORT_HTTP}} ; \
export AVSPASS=$${AVSPASS:-nopasswordset} ; \
stack $(STACK_CORES) exec --local-bin-path $$(pwd)/bin --copy-bins -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}"
.PHONY: clean
clean:
rm -rf .stack-work .stack uniworx.cabal .ghc

View File

@ -8,7 +8,7 @@
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
#DEVELOPMENT ONLY, NOT TO BE USED IN PRODUCTION
# DEVELOPMENT ONLY, NOT TO BE USED IN PRODUCTION
avs-licence-synch:
times: [12]
@ -17,14 +17,16 @@ avs-licence-synch:
max-changes: 999
mail-reroute-to:
name: FRADrive-QA-Umleitungen
email: FRADrive-TEST-Umleitungen@fraport.de
name: "FRADrive-QA-Umleitungen"
email: "FRADrive-TEST-Umleitungen@fraport.de"
# Enqueue at specified hour, a few minutes later
job-lms-qualifications-enqueue-hour: 16
job-lms-qualifications-dequeue-hour: 4
job-mode:
tag: offload
job-workers: 1
job-flush-interval: 600
# Using these setting kills the job-workers somehow
# job-workers: 5
# job-flush-interval: 600
# job-stale-threshold: 3600
# job-move-threshold: 60

View File

@ -16,5 +16,4 @@ log-settings:
auth-dummy-login: true
server-session-acid-fallback: true
job-cron-interval: null
job-workers: 1
job-workers: 20

View File

View File

@ -47,9 +47,11 @@ TutorialUserDeregister: Vom Kurs abmelden
TutorialUserSendMail: Mitteilung verschicken
TutorialUserPrintQualification: Zertifikat drucken
TutorialUserGrantQualification: Qualifikation vergeben
TutorialUserGrantQualificationDateTooltip: Leer lassen, um das Ablaufdatum auf das heutige Datum plus Standardgültigkeitsdauer zu setzen.
TutorialUserGrantQualificationDateError qsh@QualificationShorthand: Qualifikation #{qsh} hat keine Standardgültigkeitsdauer, daher ist ein explizites Ablaufdatum erforderlich!
TutorialUserRenewQualification: Qualifikation regulär verlängern
TutorialUserRenewedQualification n@Int: Qualifikation für #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} regulär verlängert
TutorialUserGrantedQualification n@Int: Qualifikation erfolgreich an #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} vergeben
TutorialUserRenewedQualification qsh@QualificationShorthand n@Int: Qualifikation #{qsh} für #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} regulär verlängert.
TutorialUserGrantedQualification qsh@QualificationShorthand day@Text n@Int: Qualifikation #{qsh} bis #{day} erfolgreich an #{tshow n} Kurs-#{pluralDE n "Teilnehmer:in" "Teilnehmer:innen"} vergeben.
TutorialUserAssignExam: Zur Prüfung einteilen
TutorialUserExamAssignedFor n@Int m@Int p@Text: #{n}/#{m} zur Prüfung #{p} eingeteilt
CommTutorial: Kursmitteilung

View File

@ -43,14 +43,15 @@ TutorInviteHeading tutn: Invitation to be instructor for #{tutn}
TutorInviteExplanation: You were invited to be a instructor.
TutorCorrectorInvitationAccepted shn: You are now a corrector for #{shn}
TutorialUsersDeregistered count: Successfully deregistered #{show count} participants from course
TutorialUserDeregister: Deregister from course
TutorialUserSendMail: Send mail
TutorialUserPrintQualification: Print certificate
TutorialUserGrantQualification: Grant qualification
TutorialUserGrantQualificationDateTooltip: Leave blank for expiry on today's date plus standard qualification valid duration.
TutorialUserGrantQualificationDateError qsh@QualificationShorthand: Qualification #{qsh} has no standard valid duration. Please provide an explicit expiry date!
TutorialUserRenewQualification: Renew qualification
TutorialUserRenewedQualification n@Int: Successfully renewed qualification #{tshow n} course #{pluralEN n "user" "users"}
TutorialUserGrantedQualification n: Successfully granted qualification #{tshow n} course #{pluralEN n "user" "users"}
TutorialUserRenewedQualification qsh n: Successfully renewed #{qsh} qualification for #{pluralENsN n "course participant"}
TutorialUserGrantedQualification qsh day n: Successfully granted #{qsh} qualification until #{day} to #{pluralENsN n "course participant"}
TutorialUserAssignExam: Register for examination
TutorialUserExamAssignedFor n@Int m@Int p@Text: #{n}/#{m} enrolled for exam #{p}
CommTutorial: Course message

View File

@ -28,5 +28,8 @@ PrintLmsUser: ELearning Id
PrintJobs: Druckaufräge
PrintLetterType: Brieftypkürzel
MCActDummy: Platzhalter
MCActResendEmail: EMail Kopie versenden
MCActResendEmailTooltip: Eine unveränderte Kopie der EMail erneut versenden. Nur die vorherigen Empfänger werden offiziell aufgeführt, sie erhalten jedoch keine neue Kopie.
MCActResendEmailInfo n@Int recv@Text: #{pluralDEnN n "EMail Kopie"} wurden an #{recv} versandt.
CCActDummy: Platzhalter

View File

@ -28,5 +28,8 @@ PrintLmsUser: Elearning id
PrintJobs: Print jobs
PrintLetterType: Letter type shorthand
MCActDummy: Placeholder
MCActResendEmail: Resend email copy
MCActResendEmailTooltip: Resend an unchanged copy of the email. Only previous recipients will officially be listed, but they will not receive another copy.
MCActResendEmailInfo n recv: #{n} #{noneOneMoreEN n "email copy" "email copy" "email copies"} were sent to #{recv} only.
CCActDummy: Placeholder

Some files were not shown because too many files have changed in this diff Show More