Skip to content

Commit e24b507

Browse files
Add a daily vulnerability scan
1 parent 1041fda commit e24b507

File tree

1 file changed

+70
-12
lines changed

1 file changed

+70
-12
lines changed

.github/workflows/build.yml

+70-12
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ on:
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

2031
jobs:
2132
create-runner:
@@ -36,6 +47,7 @@ jobs:
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,7 +110,8 @@ 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
@@ -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' }}
@@ -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
@@ -359,30 +375,49 @@ jobs:
359375
-DpublishToNPM="${PUBLISH_TO_NPM}" \
360376
-DnpmPublishTrigger="${NPM_PUBLISH_TRIGGER}" \
361377
-DpublishToJBMarketplace="${PUBLISH_TO_JBPM}" \
362-
-DimageRepoBase=$IMAGE_REPO_BASE
378+
-DimageRepoBase=$IMAGE_REPO_BASE || RESULT=$?
363379
364380
{
365381
echo "leeway_sboms_dir=$sboms_dir"
366382
echo "leeway_vulnerability_reports_dir=$scans_dir"
367383
} >> $GITHUB_OUTPUT
368384
369385
cat "$scans_dir/vulnerability-summary.md" >> $GITHUB_STEP_SUMMARY
386+
387+
exit $RESULT
388+
- name: Check for Critical Vulnerabilities
389+
if: needs.configuration.outputs.is_scheduled_run == 'true'
390+
id: check_vulnerabilities
391+
shell: bash
392+
run: |
393+
# Parse vulnerability-stats.json from the scans directory
394+
CRITICAL_PACKAGES=$(jq -r '.[] | select(.critical > 0) | "\(.name): \(.critical) critical vulnerabilities"' "${{ steps.scan.outputs.leeway_vulnerability_reports_dir }}/vulnerability-stats.json")
395+
396+
# If there are critical packages, list them and fail the build
397+
if [ -n "$CRITICAL_PACKAGES" ]; then
398+
echo "::error::Critical vulnerabilities found in the following packages:"
399+
echo "$CRITICAL_PACKAGES" | tee -a $GITHUB_STEP_SUMMARY
400+
echo "affected_packages<<EOF" >> $GITHUB_OUTPUT
401+
echo "$CRITICAL_PACKAGES" >> $GITHUB_OUTPUT
402+
echo "EOF" >> $GITHUB_OUTPUT
403+
exit 1
404+
else
405+
echo "No critical vulnerabilities found."
406+
fi
370407
- name: Upload SBOMs
371408
uses: actions/upload-artifact@v4
372-
if: success()
373409
with:
374410
name: sboms
375411
path: ${{ steps.scan.outputs.leeway_sboms_dir }}
376412
- name: Upload vulnerability reports
377413
uses: actions/upload-artifact@v4
378-
if: success()
379414
with:
380415
name: vulnerability-reports
381416
path: ${{ steps.scan.outputs.leeway_vulnerability_reports_dir }}
382417
install-app:
383418
runs-on: ${{ needs.create-runner.outputs.label }}
384419
needs: [ configuration, build-gitpod, create-runner ]
385-
if: ${{ needs.configuration.outputs.is_main_branch == 'true' }}
420+
if: ${{ needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true' }}
386421
strategy:
387422
fail-fast: false
388423
matrix:
@@ -421,6 +456,7 @@ jobs:
421456
- build-gitpod
422457
- infrastructure
423458
- create-runner
459+
if: needs.configuration.outputs.is_scheduled_run != 'true'
424460
runs-on: ${{ needs.create-runner.outputs.label }}
425461
concurrency:
426462
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-install
@@ -471,7 +507,7 @@ jobs:
471507
name: "Install Monitoring Satellite"
472508
needs: [ infrastructure, build-previewctl, create-runner ]
473509
runs-on: ${{ needs.create-runner.outputs.label }}
474-
if: needs.configuration.outputs.with_monitoring == 'true'
510+
if: needs.configuration.outputs.with_monitoring == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
475511
concurrency:
476512
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-monitoring
477513
cancel-in-progress: true
@@ -502,7 +538,7 @@ jobs:
502538
runs-on: ${{ needs.create-runner.outputs.label }}
503539
container:
504540
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.32399
505-
if: needs.configuration.outputs.with_integration_tests != ''
541+
if: needs.configuration.outputs.with_integration_tests != '' && needs.configuration.outputs.is_scheduled_run != 'true'
506542
concurrency:
507543
group: ${{ needs.configuration.outputs.preview_name }}-integration-test
508544
cancel-in-progress: true
@@ -532,7 +568,7 @@ jobs:
532568
- configuration
533569
- build-gitpod
534570
- create-runner
535-
if: needs.configuration.outputs.is_main_branch == 'true'
571+
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
536572
uses: ./.github/workflows/workspace-integration-tests.yml
537573
with:
538574
version: ${{ needs.configuration.outputs.version }}
@@ -544,7 +580,7 @@ jobs:
544580
- configuration
545581
- build-gitpod
546582
- create-runner
547-
if: needs.configuration.outputs.is_main_branch == 'true'
583+
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
548584
uses: ./.github/workflows/code-updates.yml
549585
secrets: inherit
550586

@@ -554,10 +590,31 @@ jobs:
554590
- configuration
555591
- build-gitpod
556592
- create-runner
557-
if: needs.configuration.outputs.is_main_branch == 'true'
593+
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
558594
uses: ./.github/workflows/jetbrains-updates.yml
559595
secrets: inherit
560596

597+
notify-scheduled-failure:
598+
name: "Notify on scheduled run failure"
599+
if: needs.configuration.outputs.is_scheduled_run == 'true' && failure()
600+
needs:
601+
- configuration
602+
- build-gitpod
603+
- workspace-integration-tests-main
604+
- ide-code-updates
605+
- ide-jb-updates
606+
runs-on: ubuntu-latest
607+
steps:
608+
- name: Slack Notification
609+
uses: rtCamp/action-slack-notify@v2
610+
env:
611+
SLACK_WEBHOOK: ${{ secrets.WORKSPACE_SLACK_WEBHOOK }}
612+
SLACK_ICON_EMOJI: ":x:"
613+
SLACK_USERNAME: "Scheduled Build"
614+
SLACK_COLOR: "danger"
615+
SLACK_MESSAGE: "⚠️ Security Alert: Daily vulnerability scan detected critical vulnerabilities in the following packages:\n${{ needs.build-gitpod.outputs.affected_packages }}"
616+
SLACK_FOOTER: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Workflow Logs>"
617+
561618
delete-runner:
562619
if: always()
563620
needs:
@@ -570,6 +627,7 @@ jobs:
570627
- install
571628
- monitoring
572629
- integration-test
630+
- notify-scheduled-failure
573631
uses: gitpod-io/gce-github-runner/.github/workflows/delete-vm.yml@main
574632
secrets:
575633
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}

0 commit comments

Comments
 (0)