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,188 @@ 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 : ${{ matrix.runner }}
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+ runner : ubuntu-latest
174+ - platform : linux/arm64
175+ name : linux-arm64
176+ health_wait_time : 260
177+ skip_on_draft_pr : true
178+ image_stage : publish
179+ runner : ubuntu-24.04-arm
96180 steps :
97- - run : |
98- echo "Run docker test for platform ${{ matrix.platform }}"
99181 - name : Checkout
182+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
100183 uses : actions/checkout@v4
101184 with :
102185 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
186+ - name : Download image artifact
187+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
188+ uses : actions/download-artifact@v4
119189 with :
120- platforms : ${{ matrix.platform }}
190+ name : image-${{ matrix.name }}-${{ matrix.image_stage }}-${{ needs.prepare_environment.outputs.dockerfile_hash }}-artifact
191+ path : ${{ runner.temp }}
121192 - name : Set up Docker Buildx
193+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
122194 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
195+ - name : Load image
196+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
130197 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
198+ docker load --input ${{ runner.temp }}/image-${{ matrix.name }}-${{ matrix.image_stage }}.tar
199+ - name : Get and save the UID
200+ run : |
201+ echo "UID=$(id -u)" >> $GITHUB_ENV
150202 - name : Start container from previously build image and wait for successful checks
203+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
151204 run : |
152205 mkdir -p $(pwd)/ors-docker/graphs $(pwd)/ors-docker/config $(pwd)/ors-docker/elevation_cache
153206 chown -R $UID $(pwd)/ors-docker/graphs $(pwd)/ors-docker/config $(pwd)/ors-docker $(pwd)/ors-docker/elevation_cache
@@ -158,16 +211,14 @@ jobs:
158211 sed -i "s|#logging.level.org.heigit: INFO|logging.level.org.heigit: DEBUG|" docker-compose.yml
159212 # Start the first build with the docker-compose setup
160213 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
214+ ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ matrix.health_wait_time }} || (docker compose logs && exit 1)
164215 docker compose down
165216 # Set graphs data access to MMAPP
166217 sudo yq '.ors.engine.graphs_data_access = "MMAP"' -i $(pwd)/ors-docker/config/ors-config.yml
167218 # Start the container with the test image and the raw docker run command
168219 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 }}
169220 # 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 }}
221+ ./.github/utils/url_check.sh 127.0.0.1 8080 /ors/v2/health 200 ${{ matrix.health_wait_time }}
171222 # Check for correct preflight settings to avoid CORS issues with ORIGIN wildcard from the example config
172223 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 10
173224 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 200 10
@@ -177,14 +228,78 @@ jobs:
177228 docker restart ors-instance
178229 # Request preflight with https://example.com and https://example.org to see if it gets applied correctly
179230 # 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 }}
231+ ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ matrix.health_wait_time }}
181232 # It should fail with http code 403 for https://example.com since the Origin is not covered.
182233 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 403 10
183234 echo "Recreate the container to test if the graph can be properly read again"
184235 docker stop ors-instance
185236 docker container prune -f
186237 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 }}
187238 # 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 }}
239+ ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.org" 200 ${{ matrix.health_wait_time }}
189240 # It should fail with http code 403 for https://example.com since the Origin is not covered.
190241 ./.github/utils/cors_check.sh 127.0.0.1 8080 /ors/v2/isochrones/geojson "https://example.com" 403 10
242+
243+ minimal_image_tests :
244+ runs-on : ${{ matrix.runner }}
245+ needs :
246+ - prepare_environment
247+ - build_docker_images
248+ strategy :
249+ matrix :
250+ include :
251+ - platform : linux/amd64
252+ name : linux-amd64
253+ image_stage : minimal
254+ skip_on_draft_pr : false
255+ runner : ubuntu-latest
256+ - platform : linux/arm64
257+ name : linux-arm64
258+ skip_on_draft_pr : true
259+ image_stage : minimal
260+ runner : ubuntu-24.04-arm
261+ steps :
262+ - name : Checkout
263+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
264+ uses : actions/checkout@v4
265+ with :
266+ fetch-depth : 0
267+ - name : Download image artifact
268+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
269+ uses : actions/download-artifact@v4
270+ with :
271+ name : image-${{ matrix.name }}-${{ matrix.image_stage }}-${{ needs.prepare_environment.outputs.dockerfile_hash }}-artifact
272+ path : ${{ runner.temp }}
273+ - name : Load image
274+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
275+ run : |
276+ docker load --input ${{ runner.temp }}/image-${{ matrix.name }}-${{ matrix.image_stage }}.tar
277+ - name : Get and save the UID
278+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
279+ run : |
280+ echo "UID=$(id -u)" >> $GITHUB_ENV
281+ - name : Test minimal image with graph build
282+ if : ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true && matrix.skip_on_draft_pr) }}
283+ run : |
284+ mkdir -p $(pwd)/ors-docker/elevation_cache
285+ chown -R $UID $(pwd)/ors-docker/elevation_cache
286+ # Place cached elevation file
287+ cp ors-api/src/test/files/elevation/srtm_38_03.gh $(pwd)/ors-docker/elevation_cache
288+ # Start kubernetes image with graph build configured via environment variables
289+ docker run -it -d -p 8080:8082 \
290+ -u $UID:1000 \
291+ -v graphs:/home/ors/graphs \
292+ -v $(pwd)/ors-docker/elevation_cache:/home/ors/elevation_cache \
293+ -v $(pwd)/ors-api/src/test/files/heidelberg.test.pbf:/home/ors/files/heidelberg.test.pbf:ro \
294+ -e JAVA_OPTS="-server -Xmx8g" \
295+ -e server.port=8082 \
296+ -e logging.level.org.heigit=DEBUG \
297+ -e ors.engine.profile_default.build.source_file=/home/ors/files/heidelberg.test.pbf \
298+ -e ors.engine.profile_default.graph_path=/home/ors/graphs \
299+ -e ors.engine.graphs_data_access=MMAP \
300+ -e ors.engine.elevation.cache_path=/home/ors/elevation_cache \
301+ -e ors.engine.profiles.driving-car.enabled=true \
302+ --name ors-minimal-test \
303+ ${{ needs.prepare_environment.outputs.test_minimal_image_name }}
304+ # Wait for graph build and health check (kubernetes image is non-interactive)
305+ ./.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