1616 type : string
1717 description : " Whether to recreate the VM"
1818 default : " false"
19+ simulate_scheduled_run :
20+ required : false
21+ type : boolean
22+ description : " Simulate a scheduled run"
23+ default : false
24+ schedule :
25+ # Run at midnight UTC every day
26+ # Purpose: This scheduled run performs regular vulnerability scans of the codebase
27+ # and sends notifications to Slack when new critical vulnerabilities are found.
28+ # The scan results are used to maintain security standards and address issues promptly.
29+ - cron : ' 0 0 * * *'
1930
2031jobs :
2132 create-runner :
3647 cancel-in-progress : true
3748 outputs :
3849 is_main_branch : ${{ (github.head_ref || github.ref) == 'refs/heads/main' }}
50+ is_scheduled_run : ${{ github.event_name == 'schedule' || inputs.simulate_scheduled_run == true }}
3951 version : ${{ steps.branches.outputs.sanitized-branch-name }}-gha.${{github.run_number}}
4052 preview_enable : ${{ contains( steps.pr-details.outputs.pr_body, '[x] /werft with-preview') || (steps.output.outputs.with_integration_tests != '') }}
4153 preview_name : ${{ github.head_ref || github.ref_name }}
@@ -98,14 +110,15 @@ jobs:
98110 name : Build previewctl
99111 if : |
100112 (needs.configuration.outputs.pr_no_diff_skip != 'true') &&
101- (needs.configuration.outputs.preview_enable == 'true')
113+ (needs.configuration.outputs.preview_enable == 'true') &&
114+ (needs.configuration.outputs.is_scheduled_run != 'true')
102115 needs : [ configuration, create-runner ]
103116 concurrency :
104117 group : ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-build-previewctl
105118 cancel-in-progress : ${{ needs.configuration.outputs.is_main_branch == 'false' }}
106119 runs-on : ${{ needs.create-runner.outputs.label }}
107120 container :
108- image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32399
121+ image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32507
109122 steps :
110123 - uses : actions/checkout@v4
111124 - name : Setup Environment
@@ -126,7 +139,8 @@ jobs:
126139 if : |
127140 (needs.configuration.outputs.pr_no_diff_skip != 'true') &&
128141 (needs.configuration.outputs.preview_enable == 'true') &&
129- (needs.configuration.outputs.is_main_branch != 'true')
142+ (needs.configuration.outputs.is_main_branch != 'true') &&
143+ (needs.configuration.outputs.is_scheduled_run != 'true')
130144 runs-on : ${{ needs.create-runner.outputs.label }}
131145 concurrency :
132146 group : ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-infrastructure
@@ -154,6 +168,8 @@ jobs:
154168 name : Build Gitpod
155169 needs : [ configuration, create-runner ]
156170 runs-on : ${{ needs.create-runner.outputs.label }}
171+ outputs :
172+ affected_packages : ${{ steps.check_vulnerabilities.outputs.affected_packages }}
157173 concurrency :
158174 group : ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-build-gitpod
159175 cancel-in-progress : ${{ needs.configuration.outputs.is_main_branch == 'false' }}
@@ -172,7 +188,7 @@ jobs:
172188 ports :
173189 - 6379:6379
174190 container :
175- image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32399
191+ image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32507
176192 env :
177193 DB_HOST : " mysql"
178194 DB_PORT : " 23306"
@@ -299,7 +315,7 @@ jobs:
299315
300316 exit $RESULT
301317 - name : Tag the release
302- if : github.ref == 'refs/heads/main'
318+ if : github.ref == 'refs/heads/main' && needs.configuration.outputs.is_scheduled_run != 'true'
303319 run : |
304320 git config --global user.name $GITHUB_USER
305321 git config --global user.email $GITHUB_EMAIL
@@ -309,36 +325,83 @@ jobs:
309325 GITHUB_USER : roboquat
310326 GITHUB_EMAIL : roboquat@gitpod.io
311327 VERSION : ${{ needs.configuration.outputs.version }}
312-
313- trivy-scan :
314- name : " Scan Images for Vulnerabilities"
315- needs :
316- - configuration
317- - build-gitpod
318- - create-runner
319- runs-on : ${{ needs.create-runner.outputs.label }}
320- container :
321- image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32399
322- steps :
323- - uses : actions/checkout@v4
324- - name : Setup Environment
325- uses : ./.github/actions/setup-environment
326- with :
327- identity_provider : ${{ github.ref == 'refs/heads/main' && secrets.CORE_DEV_PROVIDER || secrets.DEV_PREVIEW_PROVIDER }}
328- service_account : ${{ github.ref == 'refs/heads/main' && secrets.CORE_DEV_SA || secrets.DEV_PREVIEW_SA }}
329- leeway_segment_key : ${{ secrets.LEEWAY_SEGMENT_KEY }}
330- - name : Scan Images for Vulnerabilities
328+ - name : Scan for Vulnerabilities
329+ id : scan
331330 shell : bash
332331 env :
333- INSTALLER_IMAGE_BASE_REPO : ${{needs.configuration.outputs.image_repo_base}}
332+ VERSION : ${{needs.configuration.outputs.version}}
333+ PUBLISH_TO_NPM : ${{ needs.configuration.outputs.publish_to_npm == 'true' || needs.configuration.outputs.is_main_branch == 'true' }}
334+ PUBLISH_TO_JBPM : ${{ needs.configuration.outputs.publish_to_jbmp == 'true' || needs.configuration.outputs.is_main_branch == 'true' }}
335+ LEEWAY_REMOTE_CACHE_BUCKET : ${{needs.configuration.outputs.leeway_cache_bucket}}
336+ IMAGE_REPO_BASE : ${{needs.configuration.outputs.image_repo_base}}/build
337+ run : |
338+ [[ "$PR_NO_CACHE" = "true" ]] && CACHE="none" || CACHE="remote"
339+ [[ "$PR_NO_TEST" = "true" ]] && TEST="--dont-test" || TEST=""
340+ [[ "${PUBLISH_TO_NPM}" = 'true' ]] && NPM_PUBLISH_TRIGGER=$(date +%s%3N) || NPM_PUBLISH_TRIGGER="false"
341+
342+ sboms_dir=$(mktemp -d)
343+ CI= leeway sbom export components:needs-vuln-scan --with-dependencies --output-dir "$sboms_dir" \
344+ -Dversion=$VERSION \
345+ --docker-build-options network=host \
346+ --max-concurrent-tasks 1 \
347+ -DlocalAppVersion=$VERSION \
348+ -DpublishToNPM="${PUBLISH_TO_NPM}" \
349+ -DnpmPublishTrigger="${NPM_PUBLISH_TRIGGER}" \
350+ -DpublishToJBMarketplace="${PUBLISH_TO_JBPM}" \
351+ -DimageRepoBase=$IMAGE_REPO_BASE
352+
353+ scans_dir=$(mktemp -d)
354+ CI= leeway sbom scan components:needs-vuln-scan --with-dependencies --output-dir "$scans_dir" \
355+ -Dversion=$VERSION \
356+ --docker-build-options network=host \
357+ --max-concurrent-tasks 1 \
358+ -DlocalAppVersion=$VERSION \
359+ -DpublishToNPM="${PUBLISH_TO_NPM}" \
360+ -DnpmPublishTrigger="${NPM_PUBLISH_TRIGGER}" \
361+ -DpublishToJBMarketplace="${PUBLISH_TO_JBPM}" \
362+ -DimageRepoBase=$IMAGE_REPO_BASE || RESULT=$?
363+
364+ {
365+ echo "leeway_sboms_dir=$sboms_dir"
366+ echo "leeway_vulnerability_reports_dir=$scans_dir"
367+ } >> $GITHUB_OUTPUT
368+
369+ cat "$scans_dir/vulnerability-summary.md" >> $GITHUB_STEP_SUMMARY
370+
371+ exit $RESULT
372+ - name : Check for Critical Vulnerabilities
373+ if : needs.configuration.outputs.is_scheduled_run == 'true'
374+ id : check_vulnerabilities
375+ shell : bash
334376 run : |
335- ./scripts/trivy/trivy-scan-images.sh ${{ needs.configuration.outputs.version }} CRITICAL
336- exit $?
377+ # Parse vulnerability-stats.json from the scans directory
378+ CRITICAL_PACKAGES=$(jq -r '.[] | select(.critical > 0) | "\(.name): \(.critical) critical vulnerabilities"' "${{ steps.scan.outputs.leeway_vulnerability_reports_dir }}/vulnerability-stats.json")
337379
380+ # If there are critical packages, list them and fail the build
381+ if [ -n "$CRITICAL_PACKAGES" ]; then
382+ echo "::error::Critical vulnerabilities found in the following packages:"
383+ echo "$CRITICAL_PACKAGES" | tee -a $GITHUB_STEP_SUMMARY
384+ echo "affected_packages<<EOF" >> $GITHUB_OUTPUT
385+ echo "$CRITICAL_PACKAGES" >> $GITHUB_OUTPUT
386+ echo "EOF" >> $GITHUB_OUTPUT
387+ exit 1
388+ else
389+ echo "No critical vulnerabilities found."
390+ fi
391+ - name : Upload SBOMs
392+ uses : actions/upload-artifact@v4
393+ with :
394+ name : sboms
395+ path : ${{ steps.scan.outputs.leeway_sboms_dir }}
396+ - name : Upload vulnerability reports
397+ uses : actions/upload-artifact@v4
398+ with :
399+ name : vulnerability-reports
400+ path : ${{ steps.scan.outputs.leeway_vulnerability_reports_dir }}
338401 install-app :
339402 runs-on : ${{ needs.create-runner.outputs.label }}
340- needs : [ configuration, build-gitpod, trivy-scan, create-runner ]
341- if : ${{ needs.configuration.outputs.is_main_branch == 'true' }}
403+ needs : [ configuration, build-gitpod, create-runner ]
404+ if : ${{ needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true' }}
342405 strategy :
343406 fail-fast : false
344407 matrix :
@@ -375,9 +438,9 @@ jobs:
375438 - configuration
376439 - build-previewctl
377440 - build-gitpod
378- - trivy-scan
379441 - infrastructure
380442 - create-runner
443+ if : needs.configuration.outputs.is_scheduled_run != 'true'
381444 runs-on : ${{ needs.create-runner.outputs.label }}
382445 concurrency :
383446 group : ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-install
@@ -428,7 +491,7 @@ jobs:
428491 name : " Install Monitoring Satellite"
429492 needs : [ infrastructure, build-previewctl, create-runner ]
430493 runs-on : ${{ needs.create-runner.outputs.label }}
431- if : needs.configuration.outputs.with_monitoring == 'true'
494+ if : needs.configuration.outputs.with_monitoring == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
432495 concurrency :
433496 group : ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-monitoring
434497 cancel-in-progress : true
@@ -458,8 +521,8 @@ jobs:
458521 - create-runner
459522 runs-on : ${{ needs.create-runner.outputs.label }}
460523 container :
461- image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32399
462- if : needs.configuration.outputs.with_integration_tests != ''
524+ image : eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32507
525+ if : needs.configuration.outputs.with_integration_tests != '' && needs.configuration.outputs.is_scheduled_run != 'true'
463526 concurrency :
464527 group : ${{ needs.configuration.outputs.preview_name }}-integration-test
465528 cancel-in-progress : true
@@ -489,7 +552,7 @@ jobs:
489552 - configuration
490553 - build-gitpod
491554 - create-runner
492- if : needs.configuration.outputs.is_main_branch == 'true'
555+ if : needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
493556 uses : ./.github/workflows/workspace-integration-tests.yml
494557 with :
495558 version : ${{ needs.configuration.outputs.version }}
@@ -501,7 +564,7 @@ jobs:
501564 - configuration
502565 - build-gitpod
503566 - create-runner
504- if : needs.configuration.outputs.is_main_branch == 'true'
567+ if : needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
505568 uses : ./.github/workflows/code-updates.yml
506569 secrets : inherit
507570
@@ -511,10 +574,31 @@ jobs:
511574 - configuration
512575 - build-gitpod
513576 - create-runner
514- if : needs.configuration.outputs.is_main_branch == 'true'
577+ if : needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
515578 uses : ./.github/workflows/jetbrains-updates.yml
516579 secrets : inherit
517580
581+ notify-scheduled-failure :
582+ name : " Notify on scheduled run failure"
583+ if : needs.configuration.outputs.is_scheduled_run == 'true' && failure()
584+ needs :
585+ - configuration
586+ - build-gitpod
587+ - workspace-integration-tests-main
588+ - ide-code-updates
589+ - ide-jb-updates
590+ runs-on : ubuntu-latest
591+ steps :
592+ - name : Slack Notification
593+ uses : rtCamp/action-slack-notify@v2
594+ env :
595+ SLACK_WEBHOOK : ${{ secrets.WORKSPACE_SLACK_WEBHOOK }}
596+ SLACK_ICON_EMOJI : " :x:"
597+ SLACK_USERNAME : " Scheduled Build"
598+ SLACK_COLOR : " danger"
599+ SLACK_MESSAGE : " ⚠️ Security Alert: Daily vulnerability scan detected critical vulnerabilities in the following packages:\n ${{ needs.build-gitpod.outputs.affected_packages }}"
600+ SLACK_FOOTER : " <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Workflow Logs>"
601+
518602 delete-runner :
519603 if : always()
520604 needs :
@@ -523,11 +607,11 @@ jobs:
523607 - build-previewctl
524608 - infrastructure
525609 - build-gitpod
526- - trivy-scan
527610 - install-app
528611 - install
529612 - monitoring
530613 - integration-test
614+ - notify-scheduled-failure
531615 uses : gitpod-io/gce-github-runner/.github/workflows/delete-vm.yml@main
532616 secrets :
533617 gcp_credentials : ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
0 commit comments