Release pipeline #161
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: Release pipeline | |
on: | |
push: | |
# only for version 2.x.x releases and release candidates | |
tags: | |
- v2.?.? | |
- v2.?.?-RC? | |
workflow_dispatch: | |
env: | |
# 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 | |
# for security reasons the github actions are pinned to specific release versions | |
jobs: | |
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 | |
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 server 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 | |
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 | |
desktop_windows: | |
# Build only Windows installer and provide to github Release Draft | |
name: Windows installer | |
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 clean packages | |
run: npm clean-install | |
- name: Build Windows executable | |
# code signing done later using Extended Verification (EV) with a hardware key | |
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: | |
# Build and publish MacOS installer to github Release Draft | |
# the draft name uses version and is created if it does not already exist | |
name: MacOS installer | |
runs-on: macos-latest | |
needs: [desktop_unit_tests, site_unit_tests] | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# MacOS signing: certificate and password, see electron.build/code-signing | |
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }} | |
CSC_LINK: ${{ secrets.MAC_CERTS }} | |
# MacOS notarization: see github.com/electron/notarize#readme | |
API_KEY_ID: ${{ secrets.API_KEY_ID }} | |
API_KEY_ISSUER_ID: ${{ secrets.API_KEY_ISSUER_ID }} | |
# APPLE_ID: ${{ secrets.APPLE_ID }} | |
# APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} | |
# APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
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 clean packages | |
run: npm clean-install | |
- name: Prepare for MacOS notarization | |
# Import Apple API key to support signing of app | |
run: | | |
mkdir -p ~/private_keys/ | |
echo '${{ secrets.API_KEY }}' > ~/private_keys/AuthKey_${{ secrets.API_KEY_ID }}.p8 | |
- name: Publish MacOS disk image | |
run: npm run build:desktop -- --mac --publish always | |
- 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-macos-site | |
path: './td.vue/dist-desktop/bundled/.sbom/*' | |
include-hidden-files: true | |
if-no-files-found: error | |
desktop_linux: | |
name: Linux installers | |
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 clean packages | |
run: npm clean-install | |
# Build and publish Linux installers to github Release Draft | |
# for all linux images EXCEPT for the snap | |
# Snaps do not publish, even with snapcraft installed, so use Snap Store | |
- name: Publish Linux app images | |
shell: bash | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:desktop -- --linux AppImage deb rpm --publish always | |
- 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: | |
name: Linux snap | |
runs-on: ubuntu-24.04 | |
needs: [desktop_unit_tests, site_unit_tests] | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} | |
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 clean packages | |
run: | | |
sudo snap install snapcraft --classic | |
npm clean-install | |
# Build the snap, but do not use inbuilt publish | |
# Snaps do not publish, even with snapcraft installed, so use Snap Store | |
- name: Build Linux snap | |
shell: bash | |
run: npm run build:desktop -- --linux snap | |
- name: Upload to Snap Store | |
shell: bash | |
run: snapcraft upload --release=stable dist-desktop/threat-dragon*.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 | |
dockerhub_release: | |
name: Publish to dockerhub | |
runs-on: ubuntu-24.04 | |
needs: [server_unit_tests, site_unit_tests] | |
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 to Docker Hub | |
id: docker_build_amd64 | |
uses: docker/[email protected] | |
with: | |
context: ./ | |
file: ./Dockerfile | |
builder: ${{ steps.buildx.outputs.name }} | |
push: ${{ startsWith(github.ref, 'refs/tags/v') }} | |
tags: ${{ env.IMAGE_NAME }}:${{ github.ref_name }},${{ env.IMAGE_NAME }}:stable | |
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 to Docker Hub | |
id: docker_build_arm64 | |
uses: docker/[email protected] | |
with: | |
context: ./ | |
file: ./Dockerfile | |
builder: ${{ steps.buildx.outputs.name }} | |
push: ${{ startsWith(github.ref, 'refs/tags/v') }} | |
tags: ${{ env.IMAGE_NAME }}:${{ github.ref_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 SBOM | |
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 | |
sbom_combiner: | |
name: SBOM combiner | |
runs-on: ubuntu-24.04 | |
needs: | |
- server_unit_tests | |
- desktop_macos | |
- desktop_linux | |
- desktop_linux_snap | |
- desktop_windows | |
- dockerhub_release | |
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 | |
webapp_release: | |
name: Publish web application | |
runs-on: ubuntu-24.04 | |
needs: | |
- desktop_macos | |
- desktop_linux | |
- desktop_windows | |
- sbom_combiner | |
steps: | |
- name: Check out | |
uses: actions/[email protected] | |
- name: Fetch prepared SBOM artifacts | |
uses: actions/[email protected] | |
with: | |
name: 'sboms' | |
path: 'sboms/' | |
- name: Prepare release notes | |
run: | | |
releaseVersion=${{ github.ref_name }} | |
sed -e s/2.x.x/${releaseVersion:1}/g .release-note-template.md > ./release-notes.txt | |
tar -czvf threat-dragon-sboms.zip sboms | |
- name: Create release notes | |
uses: softprops/[email protected] | |
with: | |
draft: true | |
name: "${releaseVersion:1}" | |
append_body: true | |
body_path: ./release-notes.txt | |
generate_release_notes: true | |
files: | | |
threat-dragon-sboms.zip |