use notarytool for MacOS images #228
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI pipeline | |
on: | |
push: | |
branches: | |
- main | |
workflow_dispatch: | |
env: | |
HEROKU_APP: threatdragon-v2 | |
HEROKU_EMAIL: [email protected] | |
HEROKU_HEALTH: https://www.threatdragon.com/healthz | |
# threatdragon is the working area on docker hub so use this area | |
# owasp/threat-dragon is the final release area so DO NOT use that | |
IMAGE_NAME: threatdragon/owasp-threat-dragon:latest | |
ZAP_FILE: zap-scan-push | |
# for security reasons the github actions are pinned to specific release versions | |
jobs: | |
server_unit_tests: | |
name: Server unit tests | |
runs-on: ubuntu-24.04 | |
defaults: | |
run: | |
working-directory: td.server | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: lint | |
run: npm run lint | |
- name: Unit test | |
run: npm run test:unit | |
- name: Create SBOM | |
run: npm run make-sbom | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-server | |
path: './td.server/sbom.*' | |
include-hidden-files: true | |
site_unit_tests: | |
name: Site unit tests | |
runs-on: ubuntu-24.04 | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: lint | |
run: npm run lint | |
- name: Unit test | |
run: npm run test:unit | |
desktop_unit_tests: | |
name: Desktop unit tests | |
runs-on: ubuntu-24.04 | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: lint | |
run: npm run lint:desktop | |
- name: Unit test | |
run: npm run test:desktop | |
codeql: | |
name: Analyze with codeql | |
runs-on: ubuntu-24.04 | |
needs: [server_unit_tests, site_unit_tests] | |
permissions: | |
security-events: write | |
strategy: | |
fail-fast: false | |
steps: | |
- name: Checkout repository | |
uses: actions/[email protected] | |
- name: Initialize CodeQL | |
uses: github/codeql-action/[email protected] | |
with: | |
languages: 'javascript' | |
config-file: ./.github/codeql/codeql-config.yml | |
# If you wish to specify custom queries, you can do so here or in a config file. | |
# By default, queries listed here will override any specified in a config file. | |
# Prefix the list here with "+" to use these queries and those in the config file. | |
- name: CodeQL autobuild | |
uses: github/codeql-action/[email protected] | |
- name: Perform vulnerability analysis | |
uses: github/codeql-action/[email protected] | |
build_docker_image: | |
name: Build latest docker | |
runs-on: ubuntu-24.04 | |
needs: [site_unit_tests, server_unit_tests] | |
if: github.repository == 'OWASP/threat-dragon' | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Set up QEMU | |
uses: docker/[email protected] | |
- name: Set up Docker Buildx | |
id: buildx | |
uses: docker/[email protected] | |
with: | |
install: true | |
- name: Cache Docker layers | |
uses: actions/[email protected] | |
with: | |
path: /tmp/.buildx-cache | |
key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }} | |
restore-keys: | | |
${{ runner.os }}-buildx- | |
${{ runner.os }}- | |
- name: Login to Docker Hub | |
uses: docker/[email protected] | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
# platform manifests not (yet) supported, so split out architectures | |
- name: Build for amd64 and push latest | |
id: docker_build_amd64 | |
uses: docker/[email protected] | |
with: | |
context: ./ | |
file: ./Dockerfile | |
builder: ${{ steps.buildx.outputs.name }} | |
push: true | |
tags: ${{ env.IMAGE_NAME }} | |
cache-from: type=local,src=/tmp/.buildx-cache | |
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max | |
platforms: linux/amd64 | |
load: true | |
- name: Build for arm64 and push latest-arm64 | |
id: docker_build_arm64 | |
uses: docker/[email protected] | |
with: | |
context: ./ | |
file: ./Dockerfile | |
builder: ${{ steps.buildx.outputs.name }} | |
push: true | |
tags: ${{ env.IMAGE_NAME }}-arm64 | |
cache-from: type=local,src=/tmp/.buildx-cache | |
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max | |
platforms: linux/arm64 | |
load: true | |
- name: fetch app SBOMs | |
run: docker run --rm --entrypoint tar "$IMAGE_ID" -c boms | tar -xv | |
env: | |
IMAGE_ID: ${{ steps.docker_build_amd64.outputs.imageid }} | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-container-image-app | |
path: './boms/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
- # Temp fix for large cache bug | |
# https://github.com/docker/build-push-action/issues/252 | |
name: Move cache | |
run: | | |
rm -rf /tmp/.buildx-cache | |
mv /tmp/.buildx-cache-new /tmp/.buildx-cache | |
heroku_deploy: | |
name: Upload to Heroku | |
runs-on: ubuntu-22.04 # ubuntu-24.04 does not have heroku cli, yet | |
needs: build_docker_image | |
steps: | |
- uses: actions/[email protected] | |
- uses: akhileshns/[email protected] | |
with: | |
heroku_api_key: ${{ secrets.HEROKU_API_KEY }} | |
heroku_app_name: ${{ env.HEROKU_APP }} | |
heroku_email: ${{ env.HEROKU_EMAIL }} | |
healthcheck: ${{ env.HEROKU_HEALTH }} | |
rollbackonhealthcheckfailed: true | |
usedocker: true | |
browserstack_smoke_test: | |
name: Browserstack smoke test | |
runs-on: ubuntu-24.04 | |
needs: heroku_deploy | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: BrowserStack Env Setup | |
uses: browserstack/github-actions/[email protected] | |
with: | |
username: ${{ secrets.BROWSERSTACK_USERNAME }} | |
access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} | |
- name: Run cross-browser smoke tests | |
run: npm run test:e2e-smokes | |
e2e_smokes: | |
name: Site e2e smokes | |
runs-on: ubuntu-24.04 | |
needs: build_docker_image | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Run Threat Dragon | |
run: | | |
docker run -d \ | |
-p 3000:3000 \ | |
-e ENCRYPTION_JWT_REFRESH_SIGNING_KEY='${{ secrets.CI_JWT_REFRESH_SIGNING_KEY }}' \ | |
-e ENCRYPTION_JWT_SIGNING_KEY='${{ secrets.CI_JWT_SIGNING_KEY }}' \ | |
-e ENCRYPTION_KEYS='${{ secrets.CI_SESSION_ENCRYPTION_KEYS }}' \ | |
-e GITHUB_CLIENT_ID='${{ secrets.CI_GITHUB_CLIENT_ID }}' \ | |
-e GITHUB_CLIENT_SECRET='${{ secrets.CI_GITHUB_CLIENT_SECRET }}' \ | |
-e NODE_ENV='development' \ | |
-e SERVER_API_PROTOCOL='http' \ | |
${{ env.IMAGE_NAME }} | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: Run e2e tests | |
run: npm run test:e2e-ci-smokes | |
- name: Upload e2e videos | |
uses: actions/[email protected] | |
with: | |
name: e2e_vids.zip | |
path: td.vue/tests/e2e/videos | |
if: ${{ failure() && hashFiles('td.vue/tests/e2e/videos/') != '' }} | |
e2e_tests: | |
name: Site e2e tests | |
runs-on: ubuntu-24.04 | |
needs: e2e_smokes | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Run Threat Dragon | |
run: | | |
docker run -d \ | |
-p 3000:3000 \ | |
-e GITHUB_CLIENT_ID='${{ secrets.CI_GITHUB_CLIENT_ID }}' \ | |
-e GITHUB_CLIENT_SECRET='${{ secrets.CI_GITHUB_CLIENT_SECRET }}' \ | |
-e ENCRYPTION_JWT_REFRESH_SIGNING_KEY='${{ secrets.CI_JWT_REFRESH_SIGNING_KEY }}' \ | |
-e ENCRYPTION_JWT_SIGNING_KEY='${{ secrets.CI_JWT_SIGNING_KEY }}' \ | |
-e ENCRYPTION_KEYS='${{ secrets.CI_SESSION_ENCRYPTION_KEYS }}' \ | |
-e NODE_ENV='development' \ | |
-e SERVER_API_PROTOCOL='http' \ | |
${{ env.IMAGE_NAME }} | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm clean-install | |
- name: Run e2e tests | |
run: npm run test:e2e-ci | |
- name: Upload e2e videos | |
uses: actions/[email protected] | |
with: | |
name: e2e_vids.zip | |
path: td.vue/tests/e2e/videos | |
if: ${{ failure() && hashFiles('td.vue/tests/e2e/videos/') != '' }} | |
zap_scan_web_app: | |
name: Local site zap scan | |
runs-on: ubuntu-24.04 | |
needs: build_docker_image | |
steps: | |
- name: Run Threat Dragon | |
run: | | |
docker run -d \ | |
-p 3000:3000 \ | |
-e GITHUB_CLIENT_ID='${{ secrets.CI_GITHUB_CLIENT_ID }}' \ | |
-e GITHUB_CLIENT_SECRET='${{ secrets.CI_GITHUB_CLIENT_SECRET }}' \ | |
-e ENCRYPTION_JWT_REFRESH_SIGNING_KEY='${{ secrets.CI_JWT_REFRESH_SIGNING_KEY }}' \ | |
-e ENCRYPTION_JWT_SIGNING_KEY='${{ secrets.CI_JWT_SIGNING_KEY }}' \ | |
-e ENCRYPTION_KEYS='${{ secrets.CI_SESSION_ENCRYPTION_KEYS }}' \ | |
-e NODE_ENV='development' \ | |
-e SERVER_API_PROTOCOL='http' \ | |
${{ env.IMAGE_NAME }} | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: ZAP Scan | |
uses: zaproxy/[email protected] | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
target: 'http://localhost:3000' | |
rules_file_name: '.github/workflows/.zap-rules-web.tsv' | |
allow_issue_writing: false | |
fail_action: true | |
artifact_name: ${{ env.ZAP_FILE }} | |
cmd_options: '-a' | |
scan_image_with_trivy: | |
name: Scan image with trivy | |
runs-on: ubuntu-24.04 | |
needs: build_docker_image | |
permissions: | |
contents: write | |
security-events: write | |
steps: | |
- name: Checkout | |
uses: actions/[email protected] | |
- name: Run Trivy vulnerability scanner | |
uses: aquasecurity/[email protected] | |
with: | |
image-ref: '${{ env.IMAGE_NAME }}' | |
format: 'template' | |
template: '@/contrib/sarif.tpl' | |
trivyignores: '.github/workflows/.trivyignore' | |
output: 'trivy-results.sarif' | |
- name: Upload scan results to GitHub Security tab | |
uses: github/codeql-action/[email protected] | |
with: | |
sarif_file: 'trivy-results.sarif' | |
desktop_windows_test: | |
name: Windows desktop build test | |
runs-on: windows-latest | |
needs: [desktop_unit_tests, site_unit_tests] | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Check out | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm install | |
- name: Build Windows executable | |
run: npm run build:desktop -- --windows --publish never | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-desktop-windows-site | |
path: './td.vue/dist-desktop/bundled/.sbom/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
desktop_macos_test: | |
name: MacOS desktop build test | |
runs-on: macos-latest | |
needs: [desktop_unit_tests, site_unit_tests] | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Check out | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm install | |
- name: Build MacOS disk image | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:desktop -- --mac --publish never | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-desktop-macos-site | |
path: './td.vue/dist-desktop/bundled/.sbom/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
desktop_linux_test: | |
name: Linux desktop build test | |
runs-on: ubuntu-24.04 | |
needs: [desktop_unit_tests, site_unit_tests] | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Check out | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm install | |
- name: Build Linux app images | |
shell: bash | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:desktop -- --linux AppImage deb rpm --publish never | |
- name: Print logs on error | |
if: ${{ failure() }} | |
run: find . -name "*.log" -exec cat '{}' \; -print | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-desktop-linux-site | |
path: './td.vue/dist-desktop/bundled/.sbom/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
desktop_linux_snap_test: | |
name: Linux snap build test | |
runs-on: ubuntu-24.04 | |
needs: [desktop_unit_tests, site_unit_tests] | |
defaults: | |
run: | |
working-directory: td.vue | |
steps: | |
- name: Check out | |
uses: actions/[email protected] | |
- name: Use node LTS 20.14.0 | |
uses: actions/[email protected] | |
with: | |
node-version: '20.14.0' | |
- name: Cache NPM dir | |
uses: actions/[email protected] | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-node- | |
${{ runner.os }}- | |
- name: Install packages | |
run: npm install | |
- name: Build Linux snap | |
shell: bash | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:desktop -- --linux snap | |
- name: Print logs on error | |
if: ${{ failure() }} | |
run: find . -name "*.log" -exec cat '{}' \; -print | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms-desktop-linux-snap-site | |
path: './td.vue/dist-desktop/bundled/.sbom/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
sbom_combiner_test: | |
name: SBOM combiner test | |
runs-on: ubuntu-24.04 | |
needs: | |
- server_unit_tests | |
- desktop_macos_test | |
- desktop_linux_test | |
- desktop_linux_snap_test | |
- desktop_windows_test | |
- build_docker_image | |
steps: | |
- name: Fetch prepared SBOM artifacts | |
uses: actions/[email protected] | |
with: | |
pattern: 'sboms-*' | |
merge-multiple: false | |
path: 'raw/' | |
- name: Fetch SBOMs | |
run: | | |
set -eux | |
mkdir -p sboms/threat-dragon-container-image/app/ | |
cp raw/sboms-server/sbom.json sboms/threat-dragon-server-bom.json | |
cp raw/sboms-server/sbom.xml sboms/threat-dragon-server-bom.xml | |
cp raw/sboms-desktop-windows-site/bom.json sboms/threat-dragon-desktop-windows-site-bom.json | |
cp raw/sboms-desktop-windows-site/bom.xml sboms/threat-dragon-desktop-windows-site-bom.xml | |
cp raw/sboms-desktop-macos-site/bom.json sboms/threat-dragon-desktop-macos-site-bom.json | |
cp raw/sboms-desktop-macos-site/bom.xml sboms/threat-dragon-desktop-macos-site-bom.xml | |
cp raw/sboms-desktop-linux-site/bom.json sboms/threat-dragon-desktop-linux-site-bom.json | |
cp raw/sboms-desktop-linux-site/bom.xml sboms/threat-dragon-desktop-linux-site-bom.xml | |
cp raw/sboms-desktop-linux-snap-site/bom.json sboms/threat-dragon-desktop-linux-snap-site-bom.json | |
cp raw/sboms-desktop-linux-snap-site/bom.xml sboms/threat-dragon-desktop-linux-snap-site-bom.xml | |
cp raw/sboms-container-image-app/* sboms/threat-dragon-container-image/app/ | |
- name: Save SBOM artifact | |
uses: actions/[email protected] | |
with: | |
name: sboms | |
path: 'sboms/' | |
include-hidden-files: true |