88
99env :
1010 TEST_IMAGE_NAME : ' local/openrouteservice:test'
11+ TEST_minimal_IMAGE_NAME : ' local/openrouteservice:test-minimal'
1112 BUILD_PLATFORMS : ' linux/amd64,linux/arm64'
1213
1314
@@ -18,136 +19,186 @@ jobs:
1819 runs-on : ubuntu-latest
1920 outputs :
2021 test_image_name : ${{ env.TEST_IMAGE_NAME }}
22+ test_minimal_image_name : ${{ env.TEST_minimal_IMAGE_NAME }}
2123 build_platforms : ${{ env.BUILD_PLATFORMS }}
24+ dockerfile_hash : ${{ steps.dockerfile-hash.outputs.hash }}
2225 steps :
26+ - name : Checkout
27+ uses : actions/checkout@v4
28+ - name : Generate Dockerfile hash
29+ id : dockerfile-hash
30+ run : |
31+ HASH=$(sha256sum Dockerfile | cut -d' ' -f1 | cut -c1-8)
32+ echo "hash=$HASH" >> $GITHUB_OUTPUT
2333 - run : |
2434 echo "Publish environment variables"
35+ prepare_maven_dependencies :
36+ name : Prepare Maven dependencies for ${{ matrix.name }}
37+ runs-on : ${{ matrix.runner }}
38+ needs :
39+ - prepare_environment
40+ strategy :
41+ matrix :
42+ include :
43+ - platform : linux/amd64
44+ name : linux-amd64
45+ runner : ubuntu-latest
46+ - platform : linux/arm64
47+ name : linux-arm64
48+ runner : ubuntu-24.04-arm
49+ steps :
50+ - name : Checkout
51+ uses : actions/checkout@v4
52+ with :
53+ fetch-depth : 0
54+ - name : Set up JDK 21
55+ uses : actions/setup-java@v4
56+ id : setup-java
57+ with :
58+ distribution : ' temurin'
59+ java-version : ' 21'
60+ cache : ' maven'
61+ - name : Download Maven dependencies
62+ if : steps.setup-java.outputs.cache-hit != 'true'
63+ run : |
64+ ./mvnw package -q dependency:resolve dependency:resolve-plugins -Dmaven.test.skip=true > /dev/null || true
2565 build_docker_images :
26- name : Build the docker images
27- runs-on : ubuntu-latest
66+ name : Build ${{ matrix.image_stage }} for ${{ matrix.name }}
67+ runs-on : ${{ matrix.runner }}
2868 needs :
2969 - prepare_environment
70+ - prepare_maven_dependencies
71+ strategy :
72+ matrix :
73+ include :
74+ - platform : linux/amd64
75+ name : linux-amd64
76+ runner : ubuntu-latest
77+ image_stage : publish
78+ skip_on_draft_pr : false
79+ tags : ${{ needs.prepare_environment.outputs.test_image_name }}
80+ - platform : linux/arm64
81+ name : linux-arm64
82+ runner : ubuntu-24.04-arm
83+ image_stage : publish
84+ skip_on_draft_pr : true
85+ tags : ${{ needs.prepare_environment.outputs.test_image_name }}
86+ - platform : linux/amd64
87+ name : linux-amd64
88+ runner : ubuntu-latest
89+ image_stage : minimal
90+ skip_on_draft_pr : false
91+ tags : ${{ needs.prepare_environment.outputs.test_minimal_image_name }}
92+ - platform : linux/arm64
93+ name : linux-arm64
94+ runner : ubuntu-24.04-arm
95+ image_stage : minimal
96+ skip_on_draft_pr : true
97+ tags : ${{ needs.prepare_environment.outputs.test_minimal_image_name }}
3098 steps :
3199 - name : Checkout
100+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
32101 uses : actions/checkout@v4
33102 with :
34103 fetch-depth : 0
35104 - name : Get and save the UID
105+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
36106 run : |
37107 echo "UID=$(id -u)" >> $GITHUB_ENV
38- - name : Set up QEMU
39- uses : docker/setup-qemu-action@v3
40- with :
41- platforms : ${{ needs.prepare_environment.outputs.build_platforms }}
42108 - name : Set up Docker Buildx
109+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
43110 uses : docker/setup-buildx-action@v3
44- - name : Set up JDK 17
45- id : setup-java
111+ id : setup-buildx
112+ - name : Set up JDK 21
113+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
46114 uses : actions/setup-java@v4
115+ id : setup-java
47116 with :
48117 distribution : ' temurin'
49- java-version : ' 17'
50- - name : Cache Maven packages
51- uses : actions/cache@v4
52- with :
53- path : ~/.m2
54- key : ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
55- restore-keys : ${{ runner.os }}-m2
56- - name : Prepare the maven cache dependencies
118+ java-version : ' 21'
119+ cache : ' maven'
120+ - name : Prepare Dockerfile for Maven cache
121+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
57122 run : |
58- echo "Sync the maven dependencies"
59- ./mvnw package -Dmaven.test.skip=true -B dependency:go-offline dependency:resolve-plugins dependency:resolve -q
60- # Replace all RUN ./mvnw with RUN --mount=type=cache,target=/root/.m2 ./mvnw
61- sed -i 's/RUN \.\/mvnw /RUN --mount=type=cache,target=\/root\/.m2 \.\/mvnw /g' Dockerfile
62- - name : inject maven-build-cache into docker
63- uses :
reproducible-containers/[email protected] 123+ sed -i "s|RUN \./mvnw |RUN --mount=type=cache,target=/root/.m2/repository ./mvnw |g" Dockerfile
124+ - name : Inject Maven cache into Docker build
125+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
126+ uses : ' reproducible-containers/buildkit-cache-dance@5b81f4d29dc8397a7d341dba3aeecc7ec54d6361' # v3.3.0
64127 with :
128+ builder : ${{ steps.setup-buildx.outputs.name }}
129+ dockerfile : Dockerfile
130+ skip-extraction : ${{ steps.setup-java.outputs.cache-hit }}
65131 cache-map : |
66132 {
67- "/home/runner/.m2": "/root/.m2"
133+ "/home/runner/.m2/repository ": "/root/.m2/repository "
68134 }
69- - name : Build image for platforms ${{ needs.prepare_environment.outputs.build_platforms }}
135+ - name : Build ${{ matrix.image_stage }} image stage for ${{ matrix.name }}
70136 uses : docker/build-push-action@v6
137+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
71138 with :
72139 context : .
140+ build-args : MAVEN_OPTS=-Dmaven.repo.local=/root/.m2/repository
141+ target : ${{ matrix.image_stage }}
73142 push : false
74143 load : false
75- tags : ${{ needs.prepare_environment.outputs.test_image_name }}
76- platforms : " ${{ needs.prepare_environment.outputs.build_platforms }}"
144+ tags : ${{ matrix.tags }}
145+ platforms : " ${{ matrix.platform }}"
77146 cache-from : type=gha
78147 cache-to : type=gha,mode=max
79- run_docker_image_tests :
80- name : Run & test ${{ matrix.platform }}
81- runs-on : ${{ matrix.image }}
148+ outputs : type=docker,dest=${{ runner.temp }}/image-${{ matrix.name }}-${{ matrix.image_stage }}.tar
149+ - name : Upload image artifact
150+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
151+ uses : actions/upload-artifact@v4
152+ with :
153+ name : image-${{ matrix.name }}-${{ matrix.image_stage }}-${{ needs.prepare_environment.outputs.dockerfile_hash }}-artifact
154+ path : ${{ runner.temp }}/image-${{ matrix.name }}-${{ matrix.image_stage }}.tar
155+ retention-days : 1
156+ if-no-files-found : error
157+ compression-level : 0
158+ overwrite : true
159+ docker_image_tests :
160+ name : Test ${{ matrix.name }} - publish image
161+ runs-on : ubuntu-latest
82162 needs :
83163 - prepare_environment
84164 - build_docker_images
85165 strategy :
86166 matrix :
87- platform : [ linux/amd64,linux/arm64 ]
88- image : [ ubuntu-latest ]
89- # linux/arm64 is emulated with qemu and takes ages to build the graph.
90- # Only run linux/arm64 tests on ready PR and main.
91- isDraftPR :
92- - ${{ github.event_name == 'pull_request' && github.event.pull_request.draft == true }}
93- exclude :
94- - isDraftPR : true
95- platform : linux/arm64
167+ include :
168+ - platform : linux/amd64
169+ name : linux-amd64
170+ health_wait_time : 260
171+ image_stage : publish
172+ skip_on_draft_pr : false
173+ - platform : linux/arm64
174+ name : linux-arm64
175+ health_wait_time : 260
176+ skip_on_draft_pr : true
177+ image_stage : publish
96178 steps :
97- - run : |
98- echo "Run docker test for platform ${{ matrix.platform }}"
99179 - name : Checkout
180+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
100181 uses : actions/checkout@v4
101182 with :
102183 fetch-depth : 0
103- - name : Get and save the UID
104- run : |
105- echo "UID=$(id -u)" >> $GITHUB_ENV
106- - name : Set the wait time for arm64
107- run : |
108- if [[ "${{ matrix.platform }}" == 'linux/arm64' ]]; then
109- # arm64 is emulated and takes longer to build the graph
110- echo "Set HEALTH_WAIT_TIME to 600 for arm64"
111- echo "HEALTH_WAIT_TIME=600" >> $GITHUB_ENV
112- else
113- echo "Set HEALTH_WAIT_TIME to 260 for non-arm64"
114- echo "HEALTH_WAIT_TIME=260" >> $GITHUB_ENV
115- fi
116- - name : Set up QEMU for ${{ matrix.platform }}
117- if : ${{ matrix.platform == 'linux/arm64' }}
118- uses : docker/setup-qemu-action@v3
184+ - name : Download image artifact
185+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
186+ uses : actions/download-artifact@v4
119187 with :
120- platforms : ${{ matrix.platform }}
188+ name : image-${{ matrix.name }}-${{ matrix.image_stage }}-${{ needs.prepare_environment.outputs.dockerfile_hash }}-artifact
189+ path : ${{ runner.temp }}
121190 - name : Set up Docker Buildx
191+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
122192 uses : docker/setup-buildx-action@v3
123- - name : Cache Maven packages
124- uses : actions/cache@v4
125- with :
126- path : ~/.m2
127- key : ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
128- restore-keys : ${{ runner.os }}-m2
129- - name : Prepare the maven cache dependencies
193+ - name : Load image
194+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
130195 run : |
131- # Replace all RUN ./mvnw with RUN --mount=type=cache,target=/root/.m2 ./mvnw
132- sed -i 's/RUN \.\/mvnw /RUN --mount=type=cache,target=\/root\/.m2 \.\/mvnw /g' Dockerfile
133- - name : inject maven-build-cache into docker
134- uses :
reproducible-containers/[email protected] 135- with :
136- cache-map : |
137- {
138- "/home/runner/.m2": "/root/.m2"
139- }
140- - name : Build image
141- uses : docker/build-push-action@v6
142- with :
143- context : .
144- build-args : UID=${{ env.UID }}
145- push : false
146- load : true
147- tags : ${{ needs.prepare_environment.outputs.test_image_name }}
148- platforms : " ${{ matrix.platform }}"
149- cache-from : type=gha
196+ docker load --input ${{ runner.temp }}/image-${{ matrix.name }}-${{ matrix.image_stage }}.tar
197+ - name : Get and save the UID
198+ run : |
199+ echo "UID=$(id -u)" >> $GITHUB_ENV
150200 - name : Start container from previously build image and wait for successful checks
201+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
151202 run : |
152203 mkdir -p $(pwd)/ors-docker/graphs $(pwd)/ors-docker/config $(pwd)/ors-docker/elevation_cache
153204 chown -R $UID $(pwd)/ors-docker/graphs $(pwd)/ors-docker/config $(pwd)/ors-docker $(pwd)/ors-docker/elevation_cache
@@ -158,16 +209,14 @@ jobs:
158209 sed -i "s|#logging.level.org.heigit: INFO|logging.level.org.heigit: DEBUG|" docker-compose.yml
159210 # Start the first build with the docker-compose setup
160211 docker compose up -d
161- # Check for health to turn 200 after the graphs are build and spring-boot completely started
162- ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ env.HEALTH_WAIT_TIME }}
163- # Stop the compose setup and continue with docker run
212+ ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ matrix.health_wait_time }} || (docker compose logs && exit 1)
164213 docker compose down
165214 # Set graphs data access to MMAPP
166215 sudo yq '.ors.engine.graphs_data_access = "MMAP"' -i $(pwd)/ors-docker/config/ors-config.yml
167216 # Start the container with the test image and the raw docker run command
168217 docker run -it -d -p 8080:8082 -v $(pwd)/ors-docker/graphs:/home/ors/graphs -v $(pwd)/ors-docker/config:/home/ors/config -v $(pwd)/ors-api/src/test/files/elevation:/home/ors/elevation_cache --name ors-instance ${{ needs.prepare_environment.outputs.test_image_name }}
169218 # Check for health to turn 200 after the graphs are build and spring-boot completely started
170- ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ env.HEALTH_WAIT_TIME }}
219+ ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ matrix.health_wait_time }}
171220 # Check for correct preflight settings to avoid CORS issues with ORIGIN wildcard from the example config
172221 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 10
173222 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 200 10
@@ -177,14 +226,76 @@ jobs:
177226 docker restart ors-instance
178227 # Request preflight with https://example.com and https://example.org to see if it gets applied correctly
179228 # If matrix platform is arm64, the health check will take longer
180- ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ env.HEALTH_WAIT_TIME }}
229+ ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ matrix.health_wait_time }}
181230 # It should fail with http code 403 for https://example.com since the Origin is not covered.
182231 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 403 10
183232 echo "Recreate the container to test if the graph can be properly read again"
184233 docker stop ors-instance
185234 docker container prune -f
186235 docker run -it -d -p 8080:8082 -v $(pwd)/ors-docker/graphs:/home/ors/graphs -v $(pwd)/ors-docker/config:/home/ors/config -e ors.cors.allowed_origins=https://example.org --name ors-instance ${{ needs.prepare_environment.outputs.test_image_name }}
187236 # Request preflight with https://example.com and https://example.org to see if it gets applied correctly
188- ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ env.HEALTH_WAIT_TIME }}
237+ ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ matrix.health_wait_time }}
189238 # It should fail with http code 403 for https://example.com since the Origin is not covered.
190239 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 403 10
240+
241+ minimal_image_tests :
242+ runs-on : ubuntu-latest
243+ needs :
244+ - prepare_environment
245+ - build_docker_images
246+ strategy :
247+ matrix :
248+ include :
249+ - platform : linux/amd64
250+ name : linux-amd64
251+ image_stage : minimal
252+ skip_on_draft_pr : false
253+ - platform : linux/arm64
254+ name : linux-arm64
255+ skip_on_draft_pr : true
256+ image_stage : minimal
257+ steps :
258+ - name : Checkout
259+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
260+ uses : actions/checkout@v4
261+ with :
262+ fetch-depth : 0
263+ - name : Download image artifact
264+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
265+ uses : actions/download-artifact@v4
266+ with :
267+ name : image-${{ matrix.name }}-${{ matrix.image_stage }}-${{ needs.prepare_environment.outputs.dockerfile_hash }}-artifact
268+ path : ${{ runner.temp }}
269+ - name : Load image
270+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
271+ run : |
272+ docker load --input ${{ runner.temp }}/image-linux-amd64-minimal.tar
273+ - name : Get and save the UID
274+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
275+ run : |
276+ echo "UID=$(id -u)" >> $GITHUB_ENV
277+ - name : Test minimal image with graph build
278+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
279+ run : |
280+ mkdir -p $(pwd)/ors-docker/elevation_cache
281+ chown -R $UID $(pwd)/ors-docker/elevation_cache
282+ # Place cached elevation file
283+ cp ors-api/src/test/files/elevation/srtm_38_03.gh $(pwd)/ors-docker/elevation_cache
284+ # Start kubernetes image with graph build configured via environment variables
285+ docker run -it -d -p 8080:8082 \
286+ -u $UID:1000 \
287+ -v graphs:/home/ors/graphs \
288+ -v $(pwd)/ors-docker/elevation_cache:/home/ors/elevation_cache \
289+ -v $(pwd)/ors-api/src/test/files/heidelberg.test.pbf:/home/ors/files/heidelberg.test.pbf:ro \
290+ -e JAVA_OPTS="-server -Xmx8g" \
291+ -e server.port=8082 \
292+ -e logging.level.org.heigit=DEBUG \
293+ -e ors.engine.profile_default.build.source_file=/home/ors/files/heidelberg.test.pbf \
294+ -e ors.engine.profile_default.graph_path=/home/ors/graphs \
295+ -e ors.engine.graphs_data_access=MMAP \
296+ -e ors.engine.elevation.cache_path=/home/ors/elevation_cache \
297+ -e ors.engine.profiles.driving-car.enabled=true \
298+ --name ors-minimal-test \
299+ ${{ needs.prepare_environment.outputs.test_minimal_image_name }}
300+ # Wait for graph build and health check (kubernetes image is non-interactive)
301+ ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 60 || (docker logs ors-minimal-test && exit 1)
0 commit comments