Skip to content

update setup-buildx-action to 3.4.0 in workflows #163

update setup-buildx-action to 3.4.0 in workflows

update setup-buildx-action to 3.4.0 in workflows #163

Workflow file for this run

name: CI pipeline
on:
push:
branches:
- main
workflow_dispatch:
env:
HEROKU_APP: threatdragon-v2
HEROKU_EMAIL: jon.gadsden@owasp.org
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
# 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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- 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/upload-artifact@v4.3.0
with:
name: sboms-server
path: './td.server/sbom.*'
site_unit_tests:
name: Site unit tests
runs-on: ubuntu-24.04
defaults:
run:
working-directory: td.vue
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- 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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm clean-install
- name: lint
run: npm run lint
- 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/checkout@v4.1.1
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.25.1
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/autobuild@v3.25.1
- name: Perform vulnerability analysis
uses: github/codeql-action/analyze@v3.25.1
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/checkout@v4.1.1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3.4.0
with:
install: true
- name: Setup dockerx cache
uses: actions/cache@v4.0.0
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to Docker Hub
uses: docker/login-action@v3.2.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v6.3.0
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
platforms: linux/amd64
load: true
- name: fetch app SBOMs
run: docker run --rm --entrypoint tar "$IMAGE_ID" -c boms | tar -xv
env:
IMAGE_ID: ${{ steps.docker_build.outputs.imageid }}
- name: Save SBOM artifact
uses: actions/upload-artifact@v4.3.0
with:
name: sboms-container-image-app
path: './boms/*'
if-no-files-found: error
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/checkout@v4.1.1
- uses: akhileshns/heroku-deploy@v3.13.15
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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm clean-install
- name: BrowserStack Env Setup
uses: browserstack/github-actions/setup-env@v1.0.1
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/checkout@v4.1.1
- 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/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm clean-install
- name: Run e2e tests
run: npm run test:e2e-ci-smokes
- name: Upload e2e videos
uses: actions/upload-artifact@v4.3.0
with:
name: e2e_vids.zip
path: td.vue/tests/e2e/videos
if: ${{ always() }}
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/checkout@v4.1.1
- 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/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm clean-install
- name: Run e2e tests
run: npm run test:e2e-ci
- name: Upload e2e videos
uses: actions/upload-artifact@v4.3.0
with:
name: e2e_vids.zip
path: td.vue/tests/e2e/videos
if: ${{ always() }}
zap_scan_web:
name: 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/checkout@v4.1.1
- name: ZAP Scan
uses: zaproxy/action-full-scan@v0.10.0
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
cmd_options: '-a'
scan_image_with_trivy:
name: Scan image with trivy
runs-on: ubuntu-24.04
needs: build_docker_image
permissions:
contents: write
steps:
# Need .trivyignore
- name: Checkout
uses: actions/checkout@v4.1.1
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.23.0
with:
image-ref: '${{ env.IMAGE_NAME }}'
format: 'table'
exit-code: 1
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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm install
# Build Windows installer
- name: Build Windows executable
# follow Comodo signing instructions
# comodosslstore.com/resources/comodo-code-signing-certificate-instructions
env:
# Windows signing certificate and password
CSC_KEY_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD}}
CSC_LINK: ${{ secrets.WINDOWS_CERT }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build:desktop -- --windows --publish never
- name: Print logs on error
if: ${{ failure() }}
run: find . -name "*.log" -exec cat '{}' \;
- name: Save SBOM artifact
uses: actions/upload-artifact@v4.3.0
with:
name: sboms-desktop-windows-site
path: './td.vue/dist-desktop/bundled/.sbom/*'
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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm install
- name: Prepare for MacOS notarization
# Import Apple API key for app notarization on macOS
# see github.com/samuelmeuli/action-electron-builder#notarization
run: |
mkdir -p ~/private_keys/
echo '${{ secrets.API_KEY }}' > ~/private_keys/AuthKey_${{ secrets.API_KEY_ID }}.p8
- name: Build MacOS disk image
env:
# MacOS signing certificate and password
# see github.com/samuelmeuli/action-electron-builder#code-signing
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
CSC_LINK: ${{ secrets.MAC_CERTS }}
# MacOS notarization API IDs
# see github.com/samuelmeuli/action-electron-builder#notarization
API_KEY_ID: ${{ secrets.API_KEY_ID }}
API_KEY_ISSUER_ID: ${{ secrets.API_KEY_ISSUER_ID }}
# github token is automatically provided to the action
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build:desktop -- --mac --publish never
- name: Print logs on error
if: ${{ failure() }}
run: find . -name "*.log" -exec cat '{}' \; -print
- name: Save SBOM artifact
uses: actions/upload-artifact@v4.3.0
with:
name: sboms-desktop-macos-site
path: './td.vue/dist-desktop/bundled/.sbom/*'
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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- 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/upload-artifact@v4.3.0
with:
name: sboms-desktop-linux-site
path: './td.vue/dist-desktop/bundled/.sbom/*'
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/checkout@v4.1.1
- name: Use node LTS 20.14.0
uses: actions/setup-node@v4.0.2
with:
node-version: '20.14.0'
- name: Cache NPM dir
uses: actions/cache@v4.0.0
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- 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/upload-artifact@v4.3.0
with:
name: sboms-desktop-linux-snap-site
path: './td.vue/dist-desktop/bundled/.sbom/*'
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/download-artifact@v4.1.7
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/upload-artifact@v4.3.0
with:
name: sboms
path: 'sboms/'