juice-shop
373 строки · 16.8 Кб
1name: "CI/CD Pipeline"2on:3push:4branches-ignore:5- l10n_develop6- gh-pages7paths-ignore:8- '*.md'9- 'LICENSE'10- 'monitoring/grafana-dashboard.json'11- 'screenshots/**'12tags-ignore:13- '*'14pull_request:15paths-ignore:16- '*.md'17- 'LICENSE'18- 'data/static/i18n/*.json'19- 'frontend/src/assets/i18n/*.json'20env:21NODE_DEFAULT_VERSION: 2022ANGULAR_CLI_VERSION: 1723CYCLONEDX_NPM_VERSION: '^1.12.0'24jobs:25lint:26runs-on: ubuntu-latest27steps:28- name: "Check out Git repository"29uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.030- name: "Use Node.js 18"31uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.132with:33node-version: ${{ env.NODE_DEFAULT_VERSION }}34- name: "Install CLI tools"35run: npm install -g @angular/cli@$ANGULAR_CLI_VERSION36- name: "Install application minimalistically"37run: |38npm install --ignore-scripts
39cd frontend
40npm install --ignore-scripts --legacy-peer-deps
41- name: "Lint source code"42run: npm run lint43- name: "Lint customization configs"44run: >45npm run lint:config -- -f ./config/7ms.yml &&
46npm run lint:config -- -f ./config/addo.yml &&
47npm run lint:config -- -f ./config/bodgeit.yml &&
48npm run lint:config -- -f ./config/ctf.yml &&
49npm run lint:config -- -f ./config/default.yml &&
50npm run lint:config -- -f ./config/fbctf.yml &&
51npm run lint:config -- -f ./config/juicebox.yml &&
52npm run lint:config -- -f ./config/mozilla.yml &&
53npm run lint:config -- -f ./config/oss.yml &&
54npm run lint:config -- -f ./config/quiet.yml &&
55npm run lint:config -- -f ./config/tutorial.yml &&
56npm run lint:config -- -f ./config/unsafe.yml
57coding-challenge-rsn:58runs-on: windows-latest59steps:60- name: "Check out Git repository"61uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.062- name: "Use Node.js 18"63uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.164with:65node-version: ${{ env.NODE_DEFAULT_VERSION }}66- name: "Install CLI tools"67run: npm install -g @angular/cli@$ANGULAR_CLI_VERSION68- name: "Install application"69run: npm install70- name: "Check coding challenges for accidental code discrepancies"71run: npm run rsn72test:73runs-on: ${{ matrix.os }}74strategy:75matrix:76os: [ubuntu-latest, macos-latest] # FIXME: Removed "windows-latest" due to 'Error: ENOENT: no such file or directory, open' error breaking at least on Node 20.0 constantly77node-version: [18, 20, 21, 22]78steps:79- name: "Check out Git repository"80if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')81uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.082- name: "Use Node.js ${{ matrix.node-version }}"83if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')84uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.185with:86node-version: ${{ matrix.node-version }}87- name: "Install CLI tools"88if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')89run: npm install -g @angular/cli@$ANGULAR_CLI_VERSION90- name: "Install application"91if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')92run: npm install93- name: "Execute unit tests"94if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')95uses: nick-invision/retry@943e742917ac94714d2f408a0e8320f2d1fcafcd #v2.8.396with:97timeout_minutes: 1598max_attempts: 399command: npm test100- name: "Copy unit test coverage data"101run: |102cp build/reports/coverage/frontend-tests/lcov.info frontend-lcov.info
103cp build/reports/coverage/server-tests/lcov.info server-lcov.info
104- name: "Upload unit test coverage data"105if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20'106uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 #v3.1.3107with:108name: unit-test-lcov109path: |110frontend-lcov.info
111server-lcov.info
112api-test:113runs-on: ${{ matrix.os }}114strategy:115matrix:116os: [ubuntu-latest, windows-latest, macos-latest]117node-version: [18, 20, 21, 22]118steps:119- name: "Check out Git repository"120if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')121uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0122- name: "Use Node.js ${{ matrix.node-version }}"123if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')124uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.1125with:126node-version: ${{ matrix.node-version }}127- name: "Install CLI tools"128if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')129run: npm install -g @angular/cli@$ANGULAR_CLI_VERSION130- name: "Install application"131if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')132run: npm install133- name: "Execute integration tests"134if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')135uses: nick-invision/retry@943e742917ac94714d2f408a0e8320f2d1fcafcd #v2.8.3136env:137NODE_ENV: test138with:139timeout_minutes: 5140max_attempts: 3141command: npm run frisby142- name: "Copy API test coverage data"143run: cp build/reports/coverage/api-tests/lcov.info api-lcov.info144- name: "Upload API test coverage data"145if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20'146uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 #v3.1.3147with:148name: api-test-lcov149path: |150api-lcov.info
151coverage-report:152needs: [test, api-test]153runs-on: ubuntu-latest154if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push'155steps:156- name: "Check out Git repository"157uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0158- name: "Download unit test coverage data"159uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a #v3.0.2160with:161name: unit-test-lcov162- name: "Download API test coverage data"163uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a #v3.0.2164with:165name: api-test-lcov166- name: "Publish coverage to Codeclimate"167env:168CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}169run: |170curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
171chmod +x ./cc-test-reporter
172sed -i s/SF:/SF:frontend\\//g frontend-lcov.info
173./cc-test-reporter format-coverage -t lcov -o codeclimate.frontend.json frontend-lcov.info
174./cc-test-reporter format-coverage -t lcov -o codeclimate.server.json server-lcov.info
175./cc-test-reporter format-coverage -t lcov -o codeclimate.api.json api-lcov.info
176./cc-test-reporter sum-coverage codeclimate.*.json -p 3
177./cc-test-reporter upload-coverage
178shell: bash179custom-config-test:180runs-on: ubuntu-latest181steps:182- name: "Check out Git repository"183uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0184- name: "Use Node.js 18"185uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.1186with:187node-version: ${{ env.NODE_DEFAULT_VERSION }}188- name: "Install CLI tools"189run: npm install -g @angular/cli@$ANGULAR_CLI_VERSION190- name: "Install application"191if: github.repository == 'juice-shop/juice-shop' || (github.repository != 'juice-shop/juice-shop' && matrix.os == 'ubuntu-latest' && matrix.node-version == '20')192run: npm install193- name: "Execute server tests for each custom configuration"194uses: nick-invision/retry@943e742917ac94714d2f408a0e8320f2d1fcafcd #v2.8.3195with:196timeout_minutes: 10197max_attempts: 3198command: >199NODE_ENV=7ms npm run test:server &&
200NODE_ENV=addo npm run test:server &&
201NODE_ENV=bodgeit npm run test:server &&
202NODE_ENV=ctf npm run test:server &&
203NODE_ENV=fbctf npm run test:server &&
204NODE_ENV=juicebox npm run test:server &&
205NODE_ENV=mozilla npm run test:server &&
206NODE_ENV=oss npm run test:server &&
207NODE_ENV=quiet npm run test:server &&
208NODE_ENV=tutorial npm run test:server &&
209NODE_ENV=unsafe npm run test:server
210e2e:211runs-on: ${{ matrix.os }}212strategy:213matrix:214os: [ubuntu-latest, macos-latest]215browser: [chrome] # FIXME Switch back to [chrome, firefox] after debugging extreme flakiness of Firefox on CI/CD216fail-fast: false217steps:218- name: "Check out Git repository"219uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0220- name: "Use Node.js 18"221uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.1222with:223node-version: ${{ env.NODE_DEFAULT_VERSION }}224- name: "Install CLI tools"225run: npm install -g @angular/cli226- name: "Install application"227run: npm install228- name: "Execute end-to-end tests on Ubuntu"229if: ${{ matrix.os == 'ubuntu-latest' }}230uses: cypress-io/github-action@59810ebfa5a5ac6fcfdcfdf036d1cd4d083a88f2 #v6.5.0231with:232install: false233browser: ${{ matrix.browser }}234start: npm start235wait-on: http://localhost:3000236record: true237group: ${{ matrix.browser }} @ ${{ matrix.os }}238env:239SOLUTIONS_WEBHOOK: ${{ secrets.E2E_SOLUTIONS_WEBHOOK }}240CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}241GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}242- name: "Execute end-to-end tests on Mac"243if: ${{ matrix.os == 'macos-latest' }}244uses: cypress-io/github-action@59810ebfa5a5ac6fcfdcfdf036d1cd4d083a88f2 #v6.5.0245with:246install: false247browser: ${{ matrix.browser }}248start: npm start249wait-on: http://localhost:3000250record: true251group: ${{ matrix.browser }} @ ${{ matrix.os }}252env:253CYPRESS_CACHE_FOLDER: /Users/runner/Library/Caches/Cypress254CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}255GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}256smoke-test:257runs-on: ubuntu-latest258steps:259- name: "Check out Git repository"260uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0261- name: "Use Node.js 18"262uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #v3.8.1263with:264node-version: ${{ env.NODE_DEFAULT_VERSION }}265- name: "Install CLI tools"266run: |267npm install -g @angular/cli@$ANGULAR_CLI_VERSION
268npm install -g @cyclonedx/cyclonedx-npm@$CYCLONEDX_NPM_VERSION
269npm install -g grunt-cli
270- name: "Set packaging options for Grunt"271run: |272echo "PCKG_OS_NAME=linux" >> $GITHUB_ENV
273echo "PCKG_NODE_VERSION=18" >> $GITHUB_ENV
274echo "PCKG_CPU_ARCH=x64" >> $GITHUB_ENV
275- name: "Package application"276run: |277npm install --production
278npm run package:ci
279- name: "Unpack application archive"280run: |281cd dist
282tar -zxf juice-shop-*.tgz
283- name: "Execute smoke test"284run: |285cd dist/juice-shop_*
286npm start &
287cd ../..
288chmod +x test/smoke/smoke-test.sh
289test/smoke/smoke-test.sh http://localhost:3000
290docker-test:291runs-on: ubuntu-latest292steps:293- name: "Check out Git repository"294uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0295- name: "Execute smoke test on Docker"296run: docker compose -f docker-compose.test.yml up --exit-code-from sut297docker:298if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push' && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master')299needs: [test, api-test, e2e, custom-config-test, docker-test]300runs-on: ubuntu-latest301steps:302- name: "Check out Git repository"303uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0304- name: "Set up QEMU"305uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0306- name: "Set up Docker Buildx"307uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 #v3.0.0308- name: "Login to DockerHub"309uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d #v3.0.0310with:311username: ${{ secrets.DOCKERHUB_USERNAME }}312password: ${{ secrets.DOCKERHUB_TOKEN }}313- name: "Set tag & labels for ${{ github.ref }}"314run: |315if [ "$GITHUB_REF" == "refs/heads/master" ]; then
316echo "DOCKER_TAG=latest" >> $GITHUB_ENV
317else
318echo "DOCKER_TAG=snapshot" >> $GITHUB_ENV
319fi
320echo "VCS_REF=`git rev-parse --short HEAD`" >> $GITHUB_ENV
321echo "BUILD_DATE=`date -u +”%Y-%m-%dT%H:%M:%SZ”`" >> $GITHUB_ENV
322- name: "Build and push for AMD64 and ARM64 processors"323uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0324with:325context: .326file: ./Dockerfile327platforms: linux/amd64,linux/arm64328push: true329tags: |330bkimminich/juice-shop:${{ env.DOCKER_TAG }}
331build-args: |332VCS_REF=${{ env.VCS_REF }}
333BUILD_DATE=${{ env.BUILD_DATE }}
334CYCLONEDX_NPM_VERSION=${{ env.CYCLONEDX_NPM_VERSION }}
335heroku:336if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push' && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master')337needs: [test, api-test, e2e, custom-config-test]338runs-on: ubuntu-latest339steps:340- name: "Check out Git repository"341uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0342- name: "Set Heroku app & branch for ${{ github.ref }}"343run: |344if [ "$GITHUB_REF" == "refs/heads/master" ]; then
345echo "HEROKU_APP=juice-shop" >> $GITHUB_ENV
346echo "HEROKU_BRANCH=master" >> $GITHUB_ENV
347else
348echo "HEROKU_APP=juice-shop-staging" >> $GITHUB_ENV
349echo "HEROKU_BRANCH=develop" >> $GITHUB_ENV
350fi
351- name: "Deploy ${{ github.ref }} to Heroku"352uses: akhileshns/heroku-deploy@9fd0f9faae4aa93a38d6f5e25b9128589f1371b0 #v3.12.14353with:354heroku_api_key: ${{ secrets.HEROKU_API_KEY }}355heroku_app_name: ${{ env.HEROKU_APP }}356heroku_email: bjoern.kimminich@owasp.org357branch: ${{ env.HEROKU_BRANCH }}358notify-slack:359if: github.repository == 'juice-shop/juice-shop' && github.event_name == 'push' && (success() || failure())360needs:361- docker362- heroku363- lint364- coding-challenge-rsn365- smoke-test366- coverage-report367runs-on: ubuntu-latest368steps:369- name: "Slack workflow notification"370uses: Gamesight/slack-workflow-status@26a36836c887f260477432e4314ec3490a84f309 #v1.2.0371with:372repo_token: ${{ secrets.GITHUB_TOKEN }}373slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}374