Revert "Merge branch '145-build-system-rewrite' into fradrive/merge-jost-new-build"

This reverts commit 0a6340844f, reversing
changes made to b4f3171257.
This commit is contained in:
Steffen Jost 2025-02-14 11:51:20 +01:00
parent 0a6340844f
commit 98c2189b54
27 changed files with 294 additions and 858 deletions

View File

@ -1,61 +0,0 @@
# 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 \
.
- 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

@ -1,61 +0,0 @@
# 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

@ -1,72 +0,0 @@
# 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

@ -1,141 +0,0 @@
# 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

@ -1,15 +0,0 @@
# 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

@ -1,18 +0,0 @@
# 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

@ -1,35 +0,0 @@
# 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}}

1
.gitignore vendored
View File

@ -37,7 +37,6 @@ uniworx.nix
.kateproject .kateproject
src/Handler/Assist.bak src/Handler/Assist.bak
src/Handler/Course.SnapCustom.hs src/Handler/Course.SnapCustom.hs
frontend/src/env.sass
*.orig *.orig
/instance /instance
.stack-work-* .stack-work-*

88
utils/version.pl → .gitlab-ci/version.pl Normal file → Executable file
View File

@ -7,7 +7,7 @@ use Data::Dumper;
# Version changes: # Version changes:
# v[x].[y].[z] -- Main version number # v[x].[y].[z] -- Main version number
# v[x].[y].[z]-test-[branchstring]-[num] -- test/branch/devel version number # v[x].[y].[z]-test-[branchstring]-num -- test/branch/devel version number
# on main/master: Biggest version so far, increment by occuring changes # on main/master: Biggest version so far, increment by occuring changes
# on other branches: find version; be it branch string, old format or main version number; # on other branches: find version; be it branch string, old format or main version number;
# increments from there. Increment version number, but on global conflict use new version number # increments from there. Increment version number, but on global conflict use new version number
@ -52,12 +52,12 @@ my %parKinds = (
}, },
autokind=>{ autokind=>{
arity=>1, arity=>1,
def=>'release/prod=v,release/*=t,*=t', def=>'main=v,master=v,test=t,*=t',
help=>'determine the tag kind from branch name instead of fixed value; use the first fitting glob', help=>'determine the tag kind from branch name instead of fixed value; use the first fitting glob',
}, },
change=>{ change=>{
arity=>1, arity=>1,
def=>'chore=patch,feat=minor,feature=minor,fix=patch,BREAK=major,perf=patch,refactor=patch,test=patch,style=patch,revert=patch,docs=patch,build=patch,ci=patch', def=>'chore=patch,feat=minor,feature=minor,fix=patch,BREAK=major,perf=patch,refactor=patch,test=patch,style=patch,revert=null,docs=patch,build=null,ci=null',
help=>'how to react on which commit type; can be partially given. Actions are: "null", "major", "minor", "patch" or state "invalid" for removing this type', help=>'how to react on which commit type; can be partially given. Actions are: "null", "major", "minor", "patch" or state "invalid" for removing this type',
}, },
changelog=>{ changelog=>{
@ -138,7 +138,6 @@ if($par{autokind}) {
my @rules = split /,/, $par{autokind}; my @rules = split /,/, $par{autokind};
RULES: { RULES: {
for my $r(@rules) { for my $r(@rules) {
warn "$0: Processing autokind rule '$r'\n" if $par{v};
if($r!~m#(.*)=(.*)#) { if($r!~m#(.*)=(.*)#) {
die "$0: Bad rule in autokind: $r\n"; die "$0: Bad rule in autokind: $r\n";
} }
@ -154,15 +153,14 @@ if($par{autokind}) {
if($par{'v'}) { if($par{'v'}) {
warn "VERBOSE: Parameters\n"; print "VERBOSE: Parameters\n";
for my $k(sort keys %par) { for my $k(sort keys %par) {
warn " $k: $par{$k}\n" print " $k: $par{$k}\n"
} }
} }
my %typeReact = (); my %typeReact = ();
for my $as(split /,/, $par{change}) { for my $as(split /,/, $par{change}) {
warn "$0: processing change parameter '$as'\n" if $par{v};
if($as=~m#(.*)=(.*)#) { if($as=~m#(.*)=(.*)#) {
$typeReact{$1} = $2; $typeReact{$1} = $2;
} else { } else {
@ -226,35 +224,47 @@ sub parseVersion {
warn "$0: internal error (parseVersion called on undef at $c)\n"; warn "$0: internal error (parseVersion called on undef at $c)\n";
return undef return undef
} }
my %cap = (); my ($pre,$ma,$mi,$p,$sp,$brn,$brv) = ();
if( if($v=~m#^([a-z]*)([0-9]+)$#) {
$v=~m#^(?<pre>[a-z]*)(?<ma>[0-9]+)$# || $pre = $1;
$v=~m#^(?<pre>[a-z]*)(?<ma>[0-9]+)\.(?<mi>[0-9]+)$# || $ma = $2;
$v=~m#^(?<pre>[a-z]*)(?<ma>[0-9]+)\.(?<mi>[0-9]+)\.(?<p>[0-9]+)$# || } elsif($v=~m#^([a-z]*)([0-9]+)\.([0-9]+)$#) {
$v=~m#^(?<pre>[a-z]*)(?<ma>[0-9]+)\.(?<mi>[0-9]+)\.(?<p>[0-9]+)-test-(?<sp>(?<brn>[a-z]+)-?(?<brv>[0-9\.]+))$# || $pre = $1;
$v=~m#^(?<pre>[a-z]*)(?<ma>[0-9]+)\.(?<mi>[0-9]+)\.(?<p>[0-9]+)-(?<sp>.*)$# $ma = $2;
) { $mi = $3
%cap = %+ } elsif($v=~m#^([a-z]*)([0-9]+)\.([0-9]+)\.([0-9]+)$#) {
# my ($pre,$ma,$mi,$p,$sp,$brn,$brv) = (); $pre = $1;
$ma = $2;
$mi = $3;
$p = $4;
} elsif($v=~m#^([a-z]*)([0-9]+)\.([0-9]+)\.([0-9]+)-test-([a-z]+)-([0-9\.]+)$#) {
$pre = $1;
$ma = $2;
$mi = $3;
$p = $4;
$sp = $5;
$brn = $6;
$brv = $7;
} elsif($v=~m#^([a-z]*)([0-9]+)\.([0-9]+)\.([0-9]+)-(.*)$#) {
$pre = $1;
$ma = $2;
$mi = $3;
$p = $4;
$sp = $5;
} else { } else {
warn "$0: unexpected old version number: $v\n" if $par{v}; warn "$0: unexpected old version number: $v\n" if $par{v};
return undef return undef
} }
$cap{pre} = 'v' if '' eq $cap{pre}; $pre = 'v' if '' eq $pre;
my %ret = ( return {
prefix=>$cap{pre}, prefix=>$pre,
major=>$cap{ma}, major=>$ma,
minor=>$cap{mi}, minor=>$mi,
patch=>$cap{p}, patch=>$p,
subpatch=>$cap{sp}, subpatch=>$sp,
branchname=>$cap{brn}, branchname=>$brn,
branchversion=>$cap{brv}, branchversion=>$brv,
);
if($par{v}) {
my $parsed = join '; ', map { "$_=>".($ret{$_}//'') } sort keys %ret;
warn "Version '$v' was parsed to '$parsed'\n"
} }
return \%ret
} }
#@oldVersions = sort { #@oldVersions = sort {
@ -294,7 +304,7 @@ sub vsCompare {
($v->{minor} // 0) <=> ($w->{minor} // 0) || ($v->{minor} // 0) <=> ($w->{minor} // 0) ||
($v->{patch} // 0) <=> ($w->{patch} // 0) || ($v->{patch} // 0) <=> ($w->{patch} // 0) ||
($v->{branchname} // '') cmp ($w->{branchname} // '') || ($v->{branchname} // '') cmp ($w->{branchname} // '') ||
($v->{branchversion} // 0) <=> ($w->{branchversion} // 0) || ($v->{branchversion} // '') <=> ($w->{branchversion} // '') ||
($v->{subpatch} // '') cmp ($w->{subpatch} // '') ($v->{subpatch} // '') cmp ($w->{subpatch} // '')
) )
} elsif('v' eq $v->{prefix} and 'v' ne $w->{prefix}) { } elsif('v' eq $v->{prefix} and 'v' ne $w->{prefix}) {
@ -362,7 +372,6 @@ if('-' eq $par{vcslog}) {
} }
my @versions = (); my @versions = ();
for my $v(@versionsOrig) { for my $v(@versionsOrig) {
warn "$0: Processing orig version (part 1): '$v'\n" if $par{v};
if($v=~m#^(.*?\S)\s*::::\s*(.*?)\s*::::\s*(.*)#) { if($v=~m#^(.*?\S)\s*::::\s*(.*?)\s*::::\s*(.*)#) {
push @versions, { push @versions, {
hash => $1, hash => $1,
@ -380,7 +389,6 @@ my $tag = undef;
my @versionPast = (); my @versionPast = ();
VERSION: for my $v(@versions) { VERSION: for my $v(@versions) {
warn "$0: Processing version (part 2): $v\n" if $par{v};
#if($v->{meta}=~m#tag\s*:\s*\Q$par{kind}\E(.*)\)#) { #if($v->{meta}=~m#tag\s*:\s*\Q$par{kind}\E(.*)\)#) {
# $tag=$1; # $tag=$1;
# last VERSION # last VERSION
@ -409,7 +417,6 @@ VERSION: for my $v(@versions) {
#$tag = parseVersion($tag); #$tag = parseVersion($tag);
for my $r(reverse @change) { for my $r(reverse @change) {
warn "$0: Processing change: $r\n" if $par{v};
if('major' eq $r->{react}) { if('major' eq $r->{react}) {
$tag->{major}++; $tag->{major}++;
$tag->{minor}=0; $tag->{minor}=0;
@ -456,7 +463,6 @@ my $highStart = $mainVersion ? $sortAll[0] : $sortSee[0];
my $highSee = $sortSee[0]; my $highSee = $sortSee[0];
my %reactCollect = (); my %reactCollect = ();
SEARCHVERSION: for my $v(@versions) { SEARCHVERSION: for my $v(@versions) {
warn "$0: search for version: '$v'\n" if $par{v};
next unless $v->{version}; next unless $v->{version};
next unless $v->{react}; next unless $v->{react};
$reactCollect{$v->{react}} = 1; $reactCollect{$v->{react}} = 1;
@ -468,12 +474,10 @@ SEARCHVERSION: for my $v(@versions) {
sub justVersionInc { sub justVersionInc {
my ($v, $react) = @_; my ($v, $react) = @_;
my $vv = parseVersion($v); my $vv = parseVersion($v);
$vv->{patch}++; # if $react->{patch}; # in principal a good idea to increase only when a patch action happend, but we need a new version, even if nothing happend, so we always increase patch; if there are other changes as well, it is overwritten anyways $vv->{patch}++ if $react->{patch};
do {$vv->{minor}++; $vv->{patch}=0} if $react->{minor}; do {$vv->{minor}++; $vv->{patch}=0} if $react->{minor};
do {$vv->{major}++; $vv->{minor}=0; $vv->{patch}=0} if $react->{major}; do {$vv->{major}++; $vv->{minor}=0; $vv->{patch}=0} if $react->{major};
my $ret = vsJustVersion($vv); return vsJustVersion($vv);
warn "$0: version inc from '$v' to $ret\n" if $par{v};
return $ret
} }
my $newVersion = undef; my $newVersion = undef;
@ -496,7 +500,6 @@ for(@allVersions) {
$allVersions{$_} = 1 $allVersions{$_} = 1
} }
while(exists $allVersions{$newVersion}) { while(exists $allVersions{$newVersion}) {
warn "$0: Version conflict, so we try another version, '$newVersion' exists already\n" if $par{v};
if($mainVersion) { if($mainVersion) {
die "$0: probably internal error (collision in main version)\n" die "$0: probably internal error (collision in main version)\n"
} }
@ -526,7 +529,6 @@ if($par{changelog}) {
my %seen = (); my %seen = ();
my @sects = ([]); my @sects = ([]);
for(@changelog) { for(@changelog) {
warn "$0: Changelog processing: '$_'\n" if $par{v};
push @sects, [] if m/^## /; push @sects, [] if m/^## /;
push @{$sects[-1]}, $_; push @{$sects[-1]}, $_;
if(m#/commit/([a-f0-9]+)\s*\)\s*\)\s*$#) { if(m#/commit/([a-f0-9]+)\s*\)\s*\)\s*$#) {
@ -540,7 +542,6 @@ if($par{changelog}) {
shift @sects; shift @sects;
} }
for my $s(@sects) { for my $s(@sects) {
warn "$0: Changelog processing, section search: '$s'\n" if $par{v};
my $hh = $s->[0]; my $hh = $s->[0];
chomp $hh; chomp $hh;
my $cnt = @$s; my $cnt = @$s;
@ -565,7 +566,6 @@ if($par{changelog}) {
'feature' => 'Features', 'feature' => 'Features',
); );
SELECTCHANGELOG: for my $v(@versions) { SELECTCHANGELOG: for my $v(@versions) {
warn "$0: Changelog processing, version selection: '$v'\n" if $par{v};
last SELECTCHANGELOG if $seen{$v->{hash}}; last SELECTCHANGELOG if $seen{$v->{hash}};
next unless $v->{subject}=~m#^\s*([a-z]+)\s*(!?)\s*((?:\(.*?\))?)\s*:\s*(.*?)\s*$#i; next unless $v->{subject}=~m#^\s*([a-z]+)\s*(!?)\s*((?:\(.*?\))?)\s*:\s*(.*?)\s*$#i;
my ($kind, $break, $context, $msg) = ($1, $2, $3, $4); my ($kind, $break, $context, $msg) = ($1, $2, $3, $4);

View File

@ -7,33 +7,33 @@ const standardVersionUpdaterYaml = require.resolve('standard-version-updater-yam
module.exports = { module.exports = {
scripts: { scripts: {
// postbump: './sync-versions.hs && git add -- package.yaml', // moved to bumpFiles // 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'], packageFiles: ['package.json', 'package.yaml'],
bumpFiles: [ bumpFiles: [
{ {
filename: 'package.json', filename: 'package.json',
type: 'json', type: 'json'
}, },
{ {
filename: 'package-lock.json', filename: 'package-lock.json',
type: 'json', type: 'json'
}, },
{ {
filename: 'package.yaml', filename: 'package.yaml',
updater: standardVersionUpdaterYaml, updater: standardVersionUpdaterYaml
}, },
{ {
filename: 'nix/docker/version.json', filename: 'nix/docker/version.json',
type: 'json', type: 'json'
}, },
{ {
filename: 'nix/docker/demo-version.json', filename: 'nix/docker/demo-version.json',
type: 'json', type: 'json'
}, }
], ],
commitUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/{{hash}}', commitUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/{{hash}}',
compareUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/{{previousTag}}...{{currentTag}}', compareUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/{{previousTag}}...{{currentTag}}',
issueUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/issues/{{id}}', 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,48 +2,6 @@
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. 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.
## [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) ## [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 ### Features

View File

@ -22,16 +22,16 @@ export CONTAINER_FILE
export CONTAINER_IDENT export CONTAINER_IDENT
export CF_PREFIX export CF_PREFIX
export DEVELOP export DEVELOP
export MOUNT_DIR=/mnt/fradrive
export CONTAINER_ATTACHED export CONTAINER_ATTACHED
export CONTAINER_INIT export CONTAINER_INIT
export CONTAINER_CLEANUP export CONTAINER_CLEANUP
export PROJECT_DIR=/fradrive
export SERVICE export SERVICE
export SERVICE_VARIANT ?= $(SERVICE) export SERVICE_VARIANT ?= $(SERVICE)
export JOB export JOB
export IMAGE export CONTAINER_CMD
export SET_IMAGE export SET_CONTAINER_CMD
export ENTRYPOINT export ENTRYPOINT
export EXEC_OPTS export EXEC_OPTS
@ -65,7 +65,7 @@ help:
# HELP: stop all running containers and remove all compilation results in the directory (but leave images including dependencies unharmed) # HELP: stop all running containers and remove all compilation results in the directory (but leave images including dependencies unharmed)
clean: clean:
rm -rf develop rm -rf develop
-rm -rf node_modules .npm .cache assets/icons assets/favicons static well-known config/manifest.json frontend/src/env.sass -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 .stack-work .stack-work.lock
-rm -rf bin .Dockerfile develop -rm -rf bin .Dockerfile develop
-$(CONTAINER_COMMAND) container prune --force -$(CONTAINER_COMMAND) container prune --force
@ -79,13 +79,13 @@ clean-all: clean
.PHONY: release .PHONY: release
# HELP: create, commit and push a new release # HELP: create, commit and push a new release
# TODO: only release when build and tests are passing!!!
release: release:
VERSION=`./utils/version.pl -changelog CHANGELOG.md -v` ; \ ./.gitlab-ci/version.pl -changelog CHANGELOG.md
git add CHANGELOG.md ; \ git add CHANGELOG.md
git commit -m "chore(release): $${VERSION}" ; \ VERSION=`.gitlab-ci/version.pl`
git tag $${VERSION} ; \ git tag $${VERSION}
git push origin $${VERSION} git commit -m "chore(release): $${VERSION}"
# git push
.PHONY: compile .PHONY: compile
compile: compile:
@ -103,24 +103,24 @@ start:
.PHONY: %-backend .PHONY: %-backend
%-backend: SERVICE=backend %-backend: SERVICE=backend
%-backend: SERVICE_VARIANT=backend %-backend: SERVICE_VARIANT=backend
%-backend: IMAGE=localhost/fradrive/backend %-backend: CONTAINER_CMD=localhost/fradrive/backend
%-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443" %-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443"
.PHONY: %-uniworxdb .PHONY: %-uniworxdb
%-uniworxdb: SERVICE=backend %-uniworxdb: SERVICE=backend
%-uniworxdb: SERVICE_VARIANT=uniworxdb %-uniworxdb: SERVICE_VARIANT=uniworxdb
%-uniworxdb: IMAGE=localhost/fradrive/backend %-uniworxdb: CONTAINER_CMD=localhost/fradrive/backend
.PHONY: %-ghci .PHONY: %-ghci
%-ghci: SERVICE=backend %-ghci: SERVICE=backend
%-ghci: SERVICE_VARIANT=ghci %-ghci: SERVICE_VARIANT=ghci
%-ghci: IMAGE=localhost/fradrive/backend %-ghci: CONTAINER_CMD=localhost/fradrive/backend
.PHONY: %-hoogle .PHONY: %-hoogle
%-hoogle: SERVICE=backend %-hoogle: SERVICE=backend
%-hoogle: SERVICE_VARIANT=hoogle %-hoogle: SERVICE_VARIANT=hoogle
%-hoogle: BASE_PORTS = "HOOGLE_PORT=8081" %-hoogle: BASE_PORTS = "HOOGLE_PORT=8081"
%-hoogle: IMAGE=localhost/fradrive/backend %-hoogle: CONTAINER_CMD=localhost/fradrive/backend
--start-hoogle: --start-hoogle:
HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \ HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \
stack $(STACK_CORES) hoogle -- server --local --port $${HOOGLE_PORT} stack $(STACK_CORES) hoogle -- server --local --port $${HOOGLE_PORT}
@ -128,24 +128,24 @@ start:
.PHONY: %-frontend .PHONY: %-frontend
%-frontend: SERVICE=frontend %-frontend: SERVICE=frontend
%-frontend: SERVICE_VARIANT=frontend %-frontend: SERVICE_VARIANT=frontend
%-frontend: IMAGE=localhost/fradrive/frontend %-frontend: CONTAINER_CMD=localhost/fradrive/frontend
.PHONY: %-postgres .PHONY: %-postgres
%-postgres: SERVICE=postgres %-postgres: SERVICE=postgres
%-postgres: SERVICE_VARIANT=postgres %-postgres: SERVICE_VARIANT=postgres
%-postgres: BASE_PORTS = "PGPORT=5432" %-postgres: BASE_PORTS = "PGPORT=5432"
%-postgres: IMAGE=localhost/fradrive/postgres %-postgres: CONTAINER_CMD=localhost/fradrive/postgres
.PHONY: %-memcached .PHONY: %-memcached
%-memcached: SERVICE=memcached %-memcached: SERVICE=memcached
%-memcached: SERVICE_VARIANT=memcached %-memcached: SERVICE_VARIANT=memcached
%-memcached: SET_IMAGE=$$(MEMCACHED_IMAGE) --port=`cat $$(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'` %-memcached: SET_CONTAINER_CMD=$$(MEMCACHED_IMAGE) --port=`cat $$(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'`
%-memcached: BASE_PORTS = "MEMCACHED_PORT=11211" %-memcached: BASE_PORTS = "MEMCACHED_PORT=11211"
.PHONY: %-minio .PHONY: %-minio
%-minio: SERVICE=minio %-minio: SERVICE=minio
%-minio: SERVICE_VARIANT=minio %-minio: SERVICE_VARIANT=minio
%-minio: SET_IMAGE=$$(MINIO_IMAGE) -- server `mktemp` --address=:`cat $$(CONTAINER_FILE) | grep 'UPLOAD_S3_PORT=' | sed 's/UPLOAD_S3_PORT=//'` %-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" %-minio: BASE_PORTS = "UPLOAD_S3_PORT=9000"
.PHONY: start-% .PHONY: start-%
@ -207,13 +207,18 @@ ghci: shell-ghci;
rebuild-%: rebuild-%:
$(MAKE) -- --image-build SERVICE=$* NO_CACHE=--no-cache $(MAKE) -- --image-build SERVICE=$* NO_CACHE=--no-cache
--image-build: --image-build:
ifeq "$(IMAGE)" "localhost/fradrive/$(SERVICE)" ifeq "$(CONTAINER_CMD)" "localhost/fradrive/$(SERVICE)"
rm -f .Dockerfile rm -f .Dockerfile
ln -s docker/$(SERVICE)/Dockerfile .Dockerfile ln -s docker/$(SERVICE)/Dockerfile .Dockerfile
PROJECT_DIR=/fradrive; \ MOUNT_DIR=/mnt/fradrive; \
PROJECT_DIR=/mnt/fradrive; \
if [ "$(IN_CI)" == "true" ] ; then \
PROJECT_DIR=/fradrive; \
fi; \
if [ "$(IN_CONTAINER)" == "false" ] ; then \ if [ "$(IN_CONTAINER)" == "false" ] ; then \
$(CONTAINER_COMMAND) build $(NO_CACHE) \ $(CONTAINER_COMMAND) build $(NO_CACHE) \
-v $(PWD):$${PROJECT_DIR}:rw \ -v $(PWD):$${MOUNT_DIR} \
--build-arg MOUNT_DIR=$(MOUNT_DIR) \
--build-arg PROJECT_DIR=$${PROJECT_DIR} \ --build-arg PROJECT_DIR=$${PROJECT_DIR} \
--env IN_CONTAINER=true \ --env IN_CONTAINER=true \
--env JOB=$(JOB) \ --env JOB=$(JOB) \
@ -228,22 +233,22 @@ endif
DEVELOP=`cat develop/.current` ; \ DEVELOP=`cat develop/.current` ; \
./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" "$(CONTAINER_INIT)" "$(CONTAINER_CLEANUP)" & \ ./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" "$(CONTAINER_INIT)" "$(CONTAINER_CLEANUP)" & \
CONTAINER_NAME=fradrive.$(CURR_DEV).$(CONTAINER_IDENT) ; \ CONTAINER_NAME=fradrive.$(CURR_DEV).$(CONTAINER_IDENT) ; \
if ! [ -z "$(SET_IMAGE)" ] ; \ if ! [ -z "$(SET_CONTAINER_CMD)" ] ; \
then \ then \
IMAGE="$(SET_IMAGE)" ; \ CONTAINER_CMD="$(SET_CONTAINER_CMD)" ; \
else \ else \
IMAGE=$(IMAGE) ; \ CONTAINER_CMD=$(CONTAINER_CMD) ; \
fi ; \ fi ; \
CONTAINER_ID=`$(CONTAINER_BGRUN) \ CONTAINER_ID=`$(CONTAINER_BGRUN) \
-v $(PWD):$(PROJECT_DIR):rw \ -v $(PWD):$(MOUNT_DIR) \
--env IN_CONTAINER=true \ --env IN_CONTAINER=true \
--env FRADRIVE_MAKE_TARGET="--$(JOB)-$(SERVICE_VARIANT)" \
--env CONTAINER_FILE=$(CONTAINER_FILE) \ --env CONTAINER_FILE=$(CONTAINER_FILE) \
--env CONTAINER_NAME=$${CONTAINER_NAME} \ --env CONTAINER_NAME=$${CONTAINER_NAME} \
--env JOB=$(JOB) \ --env JOB=$(JOB) \
--env SRC=$(SRC) \ --env SRC=$(SRC) \
--name $${CONTAINER_NAME} \ --name $${CONTAINER_NAME} \
$${IMAGE} \ $${CONTAINER_CMD} \
make -- --$(JOB)-$(SERVICE_VARIANT) IN_CONTAINER=true \
` ; \ ` ; \
printf "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)" ; \ printf "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)" ; \
if [[ "true" == "$(CONTAINER_ATTACHED)" ]] ; then \ if [[ "true" == "$(CONTAINER_ATTACHED)" ]] ; then \
@ -251,6 +256,7 @@ endif
fi fi
# For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J # For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J
# HELP(start-backend): start development instance # HELP(start-backend): start development instance
--start-backend: --start-backend:
export YESOD_IP_FROM_HEADER=true; \ export YESOD_IP_FROM_HEADER=true; \
@ -275,23 +281,22 @@ endif
--compile-backend: --compile-backend:
stack build $(STACK_CORES) --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin --copy-bins 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 # HELP(dependencies-backend): (re-)build backend dependencies
--dependencies-backend: #uniworx.cabal --dependencies-backend: uniworx.cabal
chown -R `id -un`:`id -gn` "$(PROJECT_DIR)"; \ stack build $(STACK_CORES) --fast --only-dependencies
stack build -j2 --only-dependencies
# HELP(lint-backend): lint backend # HELP(lint-backend): lint backend
--lint-backend: --lint-backend:
stack build $(STACK_CORES) --test --fast --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint stack build $(STACK_CORES) --test --fast --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint
# HELP(test-backend): test backend # HELP(test-backend): test backend
--test-backend: --test-backend:
stack build $(STACK_CORES) --test --coverage --fast --flag uniworx:library-only $(--DEVELOPMENT) stack build $(STACK_CORES) --test --coverage --fast --flag uniworx:library-only $(--DEVELOPMENT)
# uniworx.cabal: uniworx.cabal:
# stack exec -- hpack --force stack exec -- hpack --force
# HELP(compile-frontend): compile frontend assets # HELP(compile-frontend): compile frontend assets
--compile-frontend: node_modules assets esbuild.config.mjs frontend/src/env.sass --compile-frontend: node_modules assets esbuild.config.mjs
npm run build npm run build
--start-frontend: --compile-frontend; --start-frontend: --compile-frontend;
--dependencies-frontend: node_modules assets; --dependencies-frontend: node_modules assets static well-known;
node_modules: package.json package-lock.json node_modules: package.json package-lock.json
npm install --cache .npm --prefer-offline npm install --cache .npm --prefer-offline
package-lock.json: package.json package-lock.json: package.json
@ -303,15 +308,9 @@ 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/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 ./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 -cp assets/icons-src/*.svg assets/icons/fradrive
frontend/src/env.sass: static: node_modules assets esbuild.config.mjs
echo "\$$path: '$${PROJECT_DIR}'" > frontend/src/env.sass
static: node_modules assets esbuild.config.mjs frontend/src/env.sass
npm run build npm run build
well-known: static; well-known: static;
--lint-frontend: --compile-frontend
npm run lint
--test-frontend: --compile-frontend
npm run test
# HELP(compile-uniworxdb): clear and fill database. requires running postgres instance (use "make start-postgres" to start one) # 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) # TODO (db-m-$MIGRATION-backend): apply migration (see src/Model/Migration/Definition.hs for list of available migrations)
@ -320,7 +319,6 @@ well-known: static;
AVSPASS=${AVSPASS:-nopasswordset} ; \ AVSPASS=${AVSPASS:-nopasswordset} ; \
./bin/uniworxdb $(UNIWORXDB_OPTS) ./bin/uniworxdb $(UNIWORXDB_OPTS)
# HELP(shell-ghci): enter ghci shell. Use "make ghci SRC=<MODULE_FILE.hs>" to load specific source modules."
--shell-ghci: --shell-ghci:
stack ghci -- $(SRC) stack ghci -- $(SRC)
# --main-is uniworx:exe:uniworx # --main-is uniworx:exe:uniworx

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

@ -1,197 +1,67 @@
# SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de> # SPDX-FileCopyrightText: 2024 Sarah Vaupel <sarah.vaupel@uniworx.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # 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' pool: 'Prod Private Agent Pool'
stages: jobs:
# - job: HelloWorld
- stage: Setup # container:
jobs: # image: 'devfra.azurecr.io/de.fraport.trusted/ubuntu:22.04'
- ${{ each service in parameters.services }}: # endpoint: devfra
- template: .azure-pipelines/templates/jobs/setup_image.yaml # steps:
parameters: # - script: echo Hello, world!
imageName: ${{service.name}} # displayName: 'Run a one-line script'
imageBase: ${{service.imageBase}} # - script: |
- template: .azure-pipelines/templates/jobs/setup_dependencies.yaml # echo Add other tasks to build, test, and deploy your project.
parameters: # echo See https://aka.ms/yaml
serviceName: ${{service.name}} # displayName: 'Run a multi-line script'
dependenciesCaches: ${{service.dependenciesCaches}} - job: DockerTaskTest
dependenciesBuildPool: ${{service.buildPool}} container:
dependenciesBuildCores: ${{service.buildCores}} image: devfra.azurecr.io/de.fraport.build/tools:1.1.0
dependenciesBuildTimeout: ${{service.buildTimeout}} endpoint: devfra
steps:
- stage: Build - task: Docker@2
dependsOn: Setup name: dockerLoginDevFra
jobs: displayName: Docker Login to devfra
- ${{ each service in parameters.services }}: inputs:
- job: Build_${{service.name}} command: login
displayName: Compile ${{service.name}} containerRegistry: devFra
dependsOn: ${{service.dependsOn}} - task: Docker@2
pool: '${{service.buildPool}}' name: dockerBuild
timeoutInMinutes: ${{service.buildTimeout}} displayName: Backend image build test
container: inputs:
${{ if eq(variables.setupImages, true) }}: command: build
image: $(buildImageUpstream)/${{service.name}}:$(Build.BuildNumber) Dockerfile: docker/backend/Dockerfile
${{ else }}: buildContext: .
image: $(buildImageUpstream)/${{service.name}}:latest tags: |
endpoint: devfra $(Build.BuildNumber)
env: backend
PROJECT_DIR: $(Build.Repository.LocalPath) arguments: |
IN_CONTAINER: true --build-arg HTTPS_PROXY=http://proxy.frankfurt-airport.de:8080
IN_CI: true --build-arg HTTP_PROXY=http://proxy.frankfurt-airport.de:8080
steps: --build-arg NO_PROXY='localhost,127.0.0.1,*.docker.internal,*.azmk8s.io,devfra.azurecr.io,devfra.westeurope.data.azurecr.io'
- ${{ each dependencyCache in service.dependenciesCaches }}: --build-arg PROJECT_DIR=/fradrive
- template: .azure-pipelines/templates/steps/cache.yaml --build-arg MOUNT_DIR=/mnt/fradrive
parameters: # - job: BuildKitTest
cacheIdent: '${{service.name}}-dependencies' # container:
cacheKeys: '${{dependencyCache.key}}' # image: 'devfra.azurecr.io/de.fraport.trusted/buildkit:0.12.1'
cachePath: '${{dependencyCache.path}}' # endpoint: devfra
- ${{ each dependency in service.dependsOn }}: # steps:
- template: .azure-pipelines/templates/steps/artifact-download.yaml # - script: buildctl build \
parameters: # --frontend=dockerfile.v0 \
artifactName: '${{dependency}}' # --local context=. \
- template: .azure-pipelines/templates/steps/make.yaml # --local dockerfile=docker/backend/Dockerfile
parameters: # displayName: BuildKit test
makeJob: compile # - job: CustomBuildahTest
makeService: ${{service.name}} # container:
makeVars: 'CPU_CORES=${{service.buildCores}} STACK_CORES=-j${{service.buildCores}}' # image: 'devfra.azurecr.io/de.fraport.trusted/ubuntu:22.04'
- task: CopyFiles@2 # endpoint: devfra
displayName: Prepare ${{service.name}} build artifacts for upload # steps:
inputs: # - script: |
Contents: '${{service.buildArtifacts}}' # id
TargetFolder: '$(Build.ArtifactStagingDirectory)' # docker build --help
- task: PublishBuildArtifacts@1 # sudo apt-get -y update
displayName: Publish ${{service.name}} build artifacts # sudo apt-get -y install buildah
inputs: # buildah bud -t fradrive-backend-test --volume .:/mnt/fradrive --file docker/backend/Dockerfile
PathtoPublish: '$(Build.ArtifactStagingDirectory)' # displayName: Build buildah image
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

@ -2,4 +2,4 @@
// //
// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
module.exports = {extends: ['@commitlint/config-conventional']}; module.exports = {extends: ['@commitlint/config-conventional']}

View File

@ -1,38 +1,41 @@
ARG FROM_IMG=docker.io/library/haskell FROM docker.io/fpco/stack-build:lts-18.0
ARG FROM_TAG=8.10.4
FROM ${FROM_IMG}:${FROM_TAG} # add public key for nvidia cuda repositories
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A4B469963BF863CC
ENV LANG=de_DE.UTF-8 ENV LANG=en_US.UTF-8
# compile-time dependencies # compile-time dependencies
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get -y update && apt-get install -y libpq-dev libsodium-dev
# RUN apt-get -y update && apt-get -y install llvm # RUN apt-get -y update && apt-get -y install llvm
# RUN apt-get -y update && apt-get -y install g++ libghc-zlib-dev libpq-dev libsodium-dev pkg-config # 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 apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ # RUN apt-get -y update && apt-get -y install locales locales-all
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get -y update && apt-get install -y --no-install-recommends locales locales-all
# run-time dependencies for uniworx binary # run-time dependencies for uniworx binary
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ # RUN apt-get -y update && apt-get -y install fonts-roboto
--mount=type=cache,target=/var/lib/apt,sharing=locked \
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 pdftk
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ # RUN apt-get -y update && apt-get -y install texlive-base luatex
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get -y update && apt-get -y install texlive-latex-recommended texlive-luatex texlive-plain-generic texlive-lang-german texlive-lang-english
# locally these two should be identical, so that compilation results are written out into the file dir.
# in CI-pipelines these two should be different, so that the container caches the compilation results.
ARG MOUNT_DIR=/mnt/fradrive
ARG PROJECT_DIR=/fradrive ARG PROJECT_DIR=/fradrive
ENV PROJECT_DIR=${PROJECT_DIR}
RUN mkdir -p "${PROJECT_DIR}"; chmod -R 7777 "${PROJECT_DIR}" RUN mkdir -p "${PROJECT_DIR}"
WORKDIR ${PROJECT_DIR} RUN if [ "${PROJECT_DIR}" != "${MOUNT_DIR}" ] ; then cp -r "${MOUNT_DIR}"/* "${PROJECT_DIR}" ; fi
ENV HOME=${PROJECT_DIR}
RUN mkdir -p "${PROJECT_DIR}/.stack"
ENV STACK_ROOT="${PROJECT_DIR}/.stack" ENV STACK_ROOT="${PROJECT_DIR}/.stack"
RUN if [ ! -z "${IN_CI}" ]; then \ WORKDIR ${PROJECT_DIR}
stack install yesod-bin; \ ENV HOME=${PROJECT_DIR}
stack install hpack; \ RUN make -- --dependencies-backend STACK_ROOT=${STACK_ROOT} IN_CONTAINER=true JOB=${JOB}
fi
RUN stack install yesod-bin
RUN stack install hpack
ENV FRADRIVE_MAKE_TARGET=--start-backend
ENTRYPOINT make -- ${FRADRIVE_MAKE_TARGET} STACK_ROOT="${STACK_ROOT}" IN_CONTAINER=true CONTAINER_FILE="${CONTAINER_FILE}" JOB="${JOB}" SRC="${SRC}"
EXPOSE 3000/tcp
EXPOSE 3443/tcp

29
docker/fradrive/Dockerfile Executable file → Normal file
View File

@ -1,17 +1,16 @@
ARG FROM_IMG=docker.io/library/debian FROM debian:12.5
ARG FROM_TAG=12.5
FROM ${FROM_IMG}:${FROM_TAG} RUN apt-get -y update
# Setup locales # setup locales
# RUN apt-get update && apt-get -y install locales locales-all RUN apt-get -y install locales locales-all
# RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
# locale-gen locale-gen
# ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
# FraDrive runtime dependencies # Binary runtime dependencies
# TODO: minimize texlive dependencies, switch to basic schemes where possible # TODO: minimize texlive dependencies, switch to basic schemes where possible
# RUN apt-get -y install texlive-latex-recommended texlive-latex-extra texlive-luatex texlive-fonts-recommended texlive-fonts-extra texlive-lang-english texlive-lang-german RUN apt-get -y install texlive-latex-recommended texlive-latex-extra texlive-luatex texlive-fonts-recommended texlive-fonts-extra texlive-lang-english texlive-lang-german
# Add uniworx user and directories # Add uniworx user and directories
RUN mkdir -p /var/lib RUN mkdir -p /var/lib
@ -21,16 +20,12 @@ RUN useradd -r -g uniworx -d /var/lib/uniworx -M uniworx --uid 999
RUN mkdir -p /var/lib/uniworx && chown -R uniworx:uniworx /var/lib/uniworx RUN mkdir -p /var/lib/uniworx && chown -R uniworx:uniworx /var/lib/uniworx
RUN mkdir -p /var/log/uniworx && chown -R uniworx:uniworx /var/log/uniworx RUN mkdir -p /var/log/uniworx && chown -R uniworx:uniworx /var/log/uniworx
# Install FraDrive binaries # TODO: is this still needed?
# RUN install -d -g uniworx -o uniworx -m 0750 /var/lib/uniworx # RUN install -d -g uniworx -o uniworx -m 0750 /var/lib/uniworx
# RUN install -d -g uniworx -o uniworx -m 0755 /var/log/uniworx # RUN install -d -g uniworx -o uniworx -m 0755 /var/log/uniworx
COPY ./bin/uniworx /usr/bin/uniworx RUN cp /tmp/uniworx-bin/uniworx /usr/bin/uniworx
COPY ./bin/uniworxdb /usr/bin/uniworxdb
# COPY uniworxload /usr/bin/uniworx
COPY ./docker/fradrive/fradrive-entrypoint.sh /entrypoint.sh
RUN chmod 777 /entrypoint.sh
USER uniworx USER uniworx
ENTRYPOINT /entrypoint.sh ENTRYPOINT fradrive-entrypoint.sh
EXPOSE 8080/tcp EXPOSE 8080/tcp
VOLUME /var/lib/uniworx /var/log VOLUME /var/lib/uniworx /var/log

View File

@ -1,29 +1,32 @@
ARG FROM_IMG=docker.io/library/node FROM debian:12.5
ARG FROM_TAG=20
FROM ${FROM_IMG}:${FROM_TAG} # Basic dependencies
RUN apt-get -y update && apt-get -y install curl npm
ENV LANG=de_DE.UTF-8 # Build and watch dependencies
ENV LANGUAGE=de_DE.UTF-8
# build and watch dependencies
RUN apt-get -y update && apt-get -y install exiftool RUN apt-get -y update && apt-get -y install exiftool
RUN apt-get -y update && apt-get -y install imagemagick RUN apt-get -y update && apt-get -y install imagemagick
# test dependencies # Test dependencies
# RUN apt-get -y update && apt-get -y install chromium RUN apt-get -y update && apt-get -y install chromium
# ENV CHROME_BIN=chromium ENV CHROME_BIN=chromium
# configure npm to use given proxy if specified # TODO: use dotenv for npm version?
RUN if [ ! -z "${HTTP_PROXY}" ]; then npm config set proxy ${HTTP_PROXY}; fi RUN npm install -g n
RUN if [ ! -z "${FRAPORT_NOPROXY}" ]; then npm config set noproxy "${FRAPORT_NOPROXY}"; fi RUN n 20.17.0
ENV NODE_EXTRA_CA_CERTS="/etc/ssl/certs/ca-certificates.crt"
ENV PROJECT_DIR=/fradrive # locally these two should be identical, so that compilation results are written out into the file dir.
# in CI-pipelines these two should be different, so that the container caches the compilation results.
ARG MOUNT_DIR=/mnt/fradrive
ARG PROJECT_DIR=/fradrive
RUN mkdir -p ${PROJECT_DIR} RUN mkdir -p ${PROJECT_DIR}
RUN if [ "${PROJECT_DIR}" != "${MOUNT_DIR}" ] ; then cp -r ${MOUNT_DIR}/* ${PROJECT_DIR} ; fi
WORKDIR ${PROJECT_DIR} WORKDIR ${PROJECT_DIR}
ENV HOME=${PROJECT_DIR} ENV HOME=${PROJECT_DIR}
RUN if [ ! -z "${NPM_CUSTOM_REGISTRY}" ]; then \ #RUN make node_modules IN_CONTAINER=true
printf 'registry=${NPM_CUSTOM_REGISTRY}' > .npmrc \ #RUN make well-known IN_CONTAINER=true
; fi RUN make -- static
ENV FRADRIVE_MAKE_TARGET=start-frontend
ENTRYPOINT make -- ${FRADRIVE_MAKE_TARGET} IN_CONTAINER=true CHROME_BIN=${CHROME_BIN}

33
docker/podman/Dockerfile Normal file
View File

@ -0,0 +1,33 @@
# Debian-based podman daemon image for building docker images
# inside docker containers (e.g. gitlab runners).
#
# Yoinked with love from:
# https://www.redhat.com/sysadmin/podman-inside-container
FROM debian:12.5
RUN apt-get -y update
RUN apt-get -y install make podman podman-compose fuse-overlayfs
RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
ADD https://raw.githubusercontent.com/containers/image_build/main/podman/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/image_build/main/podman/podman-containers.conf /home/podman/.config/containers/containers.conf
RUN chown podman:podman -R /home/podman
# chmod containers.conf and adjust storage.conf to enable Fuse storage.
# RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/containers.conf
# RUN echo -e '[storage]\ndriver="zfs"\nmount_program="zfs"\nadditionalimage=/var/lib/shared\nmountopt="nodev,fsync=0"' >> /etc/containers/containers.conf
RUN chmod 644 /etc/containers/containers.conf
RUN echo '[storage]\ndriver="overlay"\n[storage.options.overlay]\nforce_mask="private"\nmount_program="/usr/bin/fuse-overlayfs"\nmountopt="nodev"' >> /etc/containers/containers.conf
RUN mkdir -p /root/.config/containers/ && echo '[storage]\ndriver="overlay"\n[storage.options.overlay]\nforce_mask="private"\nmount_program="/usr/bin/fuse-overlayfs"\nmountopt="nodev"' > /root/.config/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock
ENV _CONTAINERS_USERNS_CONFIGURED=""

View File

@ -7,8 +7,8 @@ import svgPlugin from 'esbuild-plugin-svg-bundle';
import { copy } from 'esbuild-plugin-copy'; import { copy } from 'esbuild-plugin-copy';
// import manifestPlugin from 'esbuild-plugin-manifest'; // import manifestPlugin from 'esbuild-plugin-manifest';
import manifestPlugin from 'esbuild-plugin-assets-manifest'; import manifestPlugin from 'esbuild-plugin-assets-manifest';
// import copyWithHashPlugin from '@enonic/esbuild-plugin-copy-with-hash'; import copyWithHashPlugin from '@enonic/esbuild-plugin-copy-with-hash';
// import inlineImportPlugin from 'esbuild-plugin-inline-import'; import inlineImportPlugin from 'esbuild-plugin-inline-import';
import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill'; import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill';
const staticDir = './static'; const staticDir = './static';

View File

@ -5,7 +5,7 @@ import babelParser from "@babel/eslint-parser";
export default [ export default [
js.configs.recommended, js.configs.recommended,
{ {
files: ["frontend/src/**/*.js"], files: ["**/*.js"],
plugins: {}, plugins: {},
languageOptions: { languageOptions: {
ecmaVersion: 2018, ecmaVersion: 2018,

View File

@ -1,9 +1,8 @@
// SPDX-FileCopyrightText: 2024-2025 David Mosbach <david.mosbach@uniworx.de>, Sarah Vaupel <sarah.vaupel@uniworx.de> // SPDX-FileCopyrightText: 2024 David Mosbach <david.mosbach@uniworx.de>, Sarah Vaupel <sarah.vaupel@uniworx.de>
// //
// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
// SPDX-License-Identifier: LicenseRef-Fraport-Corporate-Design // SPDX-License-Identifier: LicenseRef-Fraport-Corporate-Design
@import 'env';
$ico-width: 15px; $ico-width: 15px;
@ -110,7 +109,7 @@ $icons: new,
@each $name in $icons { @each $name in $icons {
.ico-#{$name} { .ico-#{$name} {
background-image: url('#{$path}/assets/icons/fradrive/#{$name}.svg'); background-image: url('/mnt/fradrive/assets/icons/fradrive/#{$name}.svg');
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Johannes Eder <ederj@cip.ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de> // SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Johannes Eder <ederj@cip.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 // SPDX-License-Identifier: AGPL-3.0-or-later
@ -499,14 +499,14 @@ function encrypt(plaintext, key) {
if (!key) throw new Error('Cannot encrypt plaintext without a valid key!'); if (!key) throw new Error('Cannot encrypt plaintext without a valid key!');
// TODO use const if possible // TODO use const if possible
// let plaintextB = Buffer.from(plaintext); let plaintextB = Buffer.from(plaintext);
// let cipherB = Buffer.alloc(plaintextB.length + sodium.crypto_secretbox_MACBYTES); let cipherB = Buffer.alloc(plaintextB.length + sodium.crypto_secretbox_MACBYTES);
// let nonceB = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES); let nonceB = undefined; // Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
// let keyB = Buffer.from(key); let keyB = Buffer.from(key);
// sodium.crypto_secretbox_easy(cipherB, plaintextB, nonceB, keyB); // sodium.crypto_secretbox_easy(cipherB, plaintextB, nonceB, keyB);
const result = null; // cipherB; const result = cipherB;
console.log('encrypt result', result); console.log('encrypt result', result);
return result; return result;
} }
@ -519,10 +519,10 @@ function decrypt(ciphertext, key) {
if (!key) throw new Error('Cannot decrypt ciphertext without a valid key!'); if (!key) throw new Error('Cannot decrypt ciphertext without a valid key!');
// TODO use const if possible // TODO use const if possible
// let cipherB = Buffer.from(ciphertext); let cipherB = Buffer.from(ciphertext);
let plaintextB = null; // Buffer.alloc(cipherB.length - sodium.crypto_secretbox_MACBYTES); let plaintextB = undefined; Buffer.alloc(cipherB.length - sodium.crypto_secretbox_MACBYTES);
// let nonceB = undefined; Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES); let nonceB = undefined; Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
// let keyB = Buffer.from(key); let keyB = Buffer.from(key);
// sodium.crypto_secretbox_open_easy(plaintextB, cipherB, nonceB, keyB); // sodium.crypto_secretbox_open_easy(plaintextB, cipherB, nonceB, keyB);

View File

@ -2,7 +2,7 @@
// //
// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
/* eslint-disable */
module.exports = function(config) { module.exports = function(config) {
config.set({ config.set({
//root path location to resolve paths defined in files and exclude //root path location to resolve paths defined in files and exclude

61
package-lock.json generated
View File

@ -68,7 +68,6 @@
"karma-browserify": "^8.1.0", "karma-browserify": "^8.1.0",
"karma-chrome-launcher": "^3.2.0", "karma-chrome-launcher": "^3.2.0",
"karma-cli": "^2.0.0", "karma-cli": "^2.0.0",
"karma-esbuild": "^2.3.0",
"karma-jasmine": "^5.1.0", "karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^2.1.0", "karma-jasmine-html-reporter": "^2.1.0",
"karma-mocha-reporter": "^2.2.5", "karma-mocha-reporter": "^2.2.5",
@ -5815,9 +5814,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/cookie": { "node_modules/cookie": {
"version": "0.7.2", "version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -5983,9 +5982,9 @@
} }
}, },
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6879,9 +6878,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/elliptic": { "node_modules/elliptic": {
"version": "6.6.1", "version": "6.5.7",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
"integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6939,9 +6938,9 @@
} }
}, },
"node_modules/engine.io": { "node_modules/engine.io": {
"version": "6.6.2", "version": "6.5.5",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
"integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6950,7 +6949,7 @@
"@types/node": ">=10.0.0", "@types/node": ">=10.0.0",
"accepts": "~1.3.4", "accepts": "~1.3.4",
"base64id": "2.0.0", "base64id": "2.0.0",
"cookie": "~0.7.2", "cookie": "~0.4.1",
"cors": "~2.8.5", "cors": "~2.8.5",
"debug": "~4.3.1", "debug": "~4.3.1",
"engine.io-parser": "~5.2.1", "engine.io-parser": "~5.2.1",
@ -10114,20 +10113,6 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/karma-esbuild": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/karma-esbuild/-/karma-esbuild-2.3.0.tgz",
"integrity": "sha512-iW3DjSGohEEkufSDmXRPZP7CNP0ye+Xt8fBCcenLqPL2u8+VHZYwlzwYyfs60vjhdf1i04xekhzI7gu8as1CLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": "^3.5.1",
"source-map": "0.6.1"
},
"peerDependencies": {
"esbuild": ">=0.17.0"
}
},
"node_modules/karma-jasmine": { "node_modules/karma-jasmine": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz",
@ -10940,9 +10925,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.8", "version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -11226,9 +11211,9 @@
} }
}, },
"node_modules/npm-run-all/node_modules/cross-spawn": { "node_modules/npm-run-all/node_modules/cross-spawn": {
"version": "6.0.6", "version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -16946,9 +16931,9 @@
} }
}, },
"node_modules/socket.io": { "node_modules/socket.io": {
"version": "4.8.1", "version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -16956,7 +16941,7 @@
"base64id": "~2.0.0", "base64id": "~2.0.0",
"cors": "~2.8.5", "cors": "~2.8.5",
"debug": "~4.3.2", "debug": "~4.3.2",
"engine.io": "~6.6.0", "engine.io": "~6.5.2",
"socket.io-adapter": "~2.5.2", "socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4" "socket.io-parser": "~4.2.4"
}, },

View File

@ -54,7 +54,6 @@
"karma-browserify": "^8.1.0", "karma-browserify": "^8.1.0",
"karma-chrome-launcher": "^3.2.0", "karma-chrome-launcher": "^3.2.0",
"karma-cli": "^2.0.0", "karma-cli": "^2.0.0",
"karma-esbuild": "^2.3.0",
"karma-jasmine": "^5.1.0", "karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^2.1.0", "karma-jasmine-html-reporter": "^2.1.0",
"karma-mocha-reporter": "^2.2.5", "karma-mocha-reporter": "^2.2.5",
@ -90,9 +89,6 @@
}, },
"scripts": { "scripts": {
"build": "node esbuild.config.mjs", "build": "node esbuild.config.mjs",
"start": "node esbuild.config.mjs --watch", "start": "node esbuild.config.mjs --watch"
"lint": "eslint --config eslint.config.mjs --color frontend/src",
"lintfix": "eslint --config eslint.config.mjs --color --fix frontend/src",
"test": "echo \"karma-testsuite currently disabled, reporting success\""
} }
} }

View File

@ -1,7 +1,6 @@
-- {-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -Wwarn -fno-warn-orphans #-}
{-# OPTIONS_GHC -Wwarn #-}
-- SPDX-FileCopyrightText: 2024-2025 Sarah Vaupel <sarah.vaupel@uniworx.de> -- SPDX-FileCopyrightText: 2024 Sarah Vaupel <sarah.vaupel@uniworx.de>
-- --
-- SPDX-License-Identifier: AGPL-3.0-or-later -- SPDX-License-Identifier: AGPL-3.0-or-later
@ -64,8 +63,9 @@ foreign import ccall unsafe "sodium_bin2hex"
bin2hex :: ByteString -> String bin2hex :: ByteString -> String
bin2hex bs = let tlen = S.length bs * 2 + 1 in bin2hex bs = let tlen = S.length bs * 2 + 1 in
S8.unpack . S8.init . snd . buildUnsafeByteString tlen $ \t -> S8.unpack . S8.init . snd . buildUnsafeByteString tlen $ \t ->
constByteStrings [bs] $ \[(pbs, _)] -> let aux [(pbs, _)] = c_sodium_bin2hex t (fromIntegral tlen) pbs (fromIntegral $ S.length bs)
c_sodium_bin2hex t (fromIntegral tlen) pbs (fromIntegral $ S.length bs) aux _ = error "Crypto.Saltine.Instances.bin2hex reached an impossible computation path"
in constByteStrings [bs] aux
instance Show Key where instance Show Key where
show k = "SecretBox.Key {hashesTo = \"" <> (bin2hex . shorthash nullShKey $ encode k) <> "}\"" show k = "SecretBox.Key {hashesTo = \"" <> (bin2hex . shorthash nullShKey $ encode k) <> "}\""

View File

@ -1,4 +1,4 @@
-- SPDX-FileCopyrightText: 2022-2025 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <s.jost@fraport.de> -- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>, Steffen Jost <s.jost@fraport.de>
-- --
-- SPDX-License-Identifier: AGPL-3.0-or-later -- SPDX-License-Identifier: AGPL-3.0-or-later