Skip to content

Add generic font family to inline font-family in macOS Help #96

Add generic font family to inline font-family in macOS Help

Add generic font family to inline font-family in macOS Help #96

Workflow file for this run

name: "Build & Analyze"
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
# ============================================================
# Compilability check + shared compilation database for SAST
# ============================================================
build:
name: Build + Compilation Database
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
bear \
build-essential autoconf \
libaspell-dev libbrotli-dev libfl-dev libfontconfig-dev \
libfreetype-dev libglib2.0-dev libkrb5-dev libldap-dev \
libpcre3-dev libsodium-dev libssl-dev libunistring-dev libxml2-dev \
libx11-dev libxext-dev libxft-dev libxpm-dev libzstd-dev \
pkg-config python3 unicode-cldr-core zlib1g-dev
- name: Configure
run: |
autoconf
./configure
- name: Build and generate compilation database
run: bear -- make -j$(nproc)
- name: Upload compilation database
uses: actions/upload-artifact@v7
with:
name: compilation-database
path: compile_commands.json
# ============================================================
# CodeChecker: Clang SA + Clang-Tidy + cppcheck + GCC -fanalyzer + Infer
# ============================================================
codechecker:
name: Static Analysis (CodeChecker)
needs: build
runs-on: ubuntu-latest
continue-on-error: true
permissions:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cppcheck python3 unicode-cldr-core \
libaspell-dev libbrotli-dev libfl-dev libfontconfig-dev \
libfreetype-dev libglib2.0-dev libkrb5-dev libldap-dev \
libpcre3-dev libsodium-dev libssl-dev libunistring-dev libxml2-dev \
libx11-dev libxext-dev libxft-dev libxpm-dev libzstd-dev
- name: Install Infer
run: |
INFER_VERSION=$(curl -sL https://api.github.com/repos/facebook/infer/releases/latest \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])")
echo "Installing Infer ${INFER_VERSION}"
curl -sL "https://github.com/facebook/infer/releases/download/${INFER_VERSION}/infer-linux-x86_64-${INFER_VERSION}.tar.xz" \
| sudo tar xJ -C /opt
sudo mv "/opt/infer-linux-x86_64-${INFER_VERSION}" /opt/infer
sudo ln -sf /opt/infer/bin/infer /usr/local/bin/infer
infer --version
- name: Download compilation database
uses: actions/download-artifact@v8
with:
name: compilation-database
- name: Generate build artifacts required for analysis
run: |
# Emoji table (generated from CLDR data at build time, gitignored)
python3 scripts/generate-emoji-table.py \
Sources_Common/i18n/Charsets/CEmojiTable.h \
/usr/share/unicode/cldr/common/annotations/en.xml \
/usr/share/unicode/cldr/common/annotationsDerived/en.xml
# Mulberry header symlinks (same as build process)
mkdir -p Linux/Includes
cd Linux && bash links.sh && cd ..
# JX include dirs (populated by JX build, not tracked in git)
mkdir -p Libraries/JX/include/jx Libraries/JX/include/jcore Libraries/JX/include/jximage
for f in Libraries/JX/libjx/code/*; do
ln -sf "../../libjx/code/$(basename "$f")" "Libraries/JX/include/jx/$(basename "$f")"
done
for f in Libraries/JX/libjcore/code/*; do
ln -sf "../../libjcore/code/$(basename "$f")" "Libraries/JX/include/jcore/$(basename "$f")"
done
for f in Libraries/JX/libjx/image/*; do
ln -sf "../../libjx/image/$(basename "$f")" "Libraries/JX/include/jximage/$(basename "$f")"
done
# JX/ACE config symlinks (created by configure)
ln -sf config-linux.h Libraries/JX/ACE/ACE_wrappers/ace/config.h
ln -sf ../include/make/sys/Linux-Intel-x86_64-gcc3 Libraries/JX/include/make/jx_config
# Fix CodeChecker report hash path resolution — it strips directory
# components from the workspace path, looking for prefix headers at
# wrong relative paths. Create symlinks at all resolved locations.
sudo mkdir -p /home/runner/work/mulberry-main/Common
sudo ln -sf ${{ github.workspace }}/Plug-ins/Common/Mac2Linux.h /home/runner/work/mulberry-main/Common/Mac2Linux.h
sudo ln -sf ${{ github.workspace }}/Plug-ins/Common/Plugin_Prefix_Linux.h /home/runner/work/mulberry-main/Common/Plugin_Prefix_Linux.h
sudo ln -sf ${{ github.workspace }}/Plug-ins/Common/os_dep.h /home/runner/work/mulberry-main/Common/os_dep.h
sudo mkdir -p /home/runner/work/Linux/Sources
sudo ln -sf ${{ github.workspace }}/Linux/Sources/Mulberry_Prefix.h /home/runner/work/Linux/Sources/Mulberry_Prefix.h
ln -sf Linux/Sources Sources
echo "Symlinks: $(find Linux/Includes -type l | wc -l) Mulberry, $(ls Libraries/JX/include/jx/*.h | wc -l) jx, $(ls Libraries/JX/include/jcore/*.h | wc -l) jcore"
- name: Filter compilation database to exclude third-party libraries
run: |
python3 -c "
import json
EXCLUDE = ['/Libraries/JX/', '/Libraries/vendor/', '/Libraries/vzic/', '/Libraries/include/', '/Libraries/openssl/']
db = json.load(open('compile_commands.json'))
filtered = [e for e in db if not any(x in e.get('file', '') for x in EXCLUDE)]
json.dump(filtered, open('compile_commands.json', 'w'), indent=2)
print(f'Filtered: {len(db)} -> {len(filtered)} entries (removed {len(db)-len(filtered)} third-party entries)')
"
- name: Run CodeChecker analysis
uses: whisperity/codechecker-analysis-action@v1
id: codechecker
with:
config: ${{ github.workspace }}/.codechecker/config.json
logfile: ${{ github.workspace }}/compile_commands.json
ctu: true
llvm-version: latest
ignore-analyze-crashes: true
- name: Convert results to SARIF
if: always()
run: |
~/.local/bin/CodeChecker parse \
${{ steps.codechecker.outputs.analyze-output }} \
--export sarif \
--output ${{ github.workspace }}/codechecker-raw.sarif \
|| true
# Fix CodeChecker SARIF bug: startColumn/endColumn of 0 violates
# SARIF spec (must be >= 1). Clamp to 1.
python3 -c "
import json
with open('${{ github.workspace }}/codechecker-raw.sarif') as f:
sarif = json.load(f)
fixed = 0
for run in sarif.get('runs', []):
for result in run.get('results', []):
for cf in result.get('codeFlows', []):
for tf in cf.get('threadFlows', []):
for loc in tf.get('locations', []):
region = loc.get('location', {}).get('physicalLocation', {}).get('region', {})
for key in ('startColumn', 'endColumn'):
if key in region and region[key] < 1:
region[key] = 1
fixed += 1
with open('${{ github.workspace }}/codechecker.sarif', 'w') as f:
json.dump(sarif, f)
print(f'SARIF fixed: {fixed} column values clamped to 1')
results = sum(len(r.get('results', [])) for r in sarif.get('runs', []))
print(f'Total results: {results}')
"
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: codechecker.sarif
category: codechecker
continue-on-error: true
- name: Upload HTML reports
if: always()
uses: actions/upload-artifact@v7
with:
name: codechecker-reports
path: ${{ steps.codechecker.outputs.result-html-dir }}
if-no-files-found: ignore
- name: Upload raw analysis results (backup)
if: always()
uses: actions/upload-artifact@v7
with:
name: codechecker-raw-results
path: ${{ steps.codechecker.outputs.analyze-output }}
if-no-files-found: ignore
# ============================================================
# PVS-Studio: deep C++ logic analysis (FOSS license)
# ============================================================
pvs-studio:
name: Static Analysis (PVS-Studio)
needs: build
runs-on: ubuntu-latest
continue-on-error: true
permissions:
security-events: write
steps:
- name: Check for credentials
id: check-creds
run: |
if [ -z "${{ secrets.PVS_STUDIO_CREDENTIALS }}" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "::notice::PVS-Studio skipped — PVS_STUDIO_CREDENTIALS secret not set"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Checkout repository
if: steps.check-creds.outputs.skip != 'true'
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install dependencies
if: steps.check-creds.outputs.skip != 'true'
run: |
sudo apt-get update
sudo apt-get install -y \
python3 unicode-cldr-core \
libaspell-dev libbrotli-dev libfl-dev libfontconfig-dev \
libfreetype-dev libglib2.0-dev libkrb5-dev libldap-dev \
libpcre3-dev libsodium-dev libssl-dev libunistring-dev libxml2-dev \
libx11-dev libxext-dev libxft-dev libxpm-dev libzstd-dev
- name: Install PVS-Studio
if: steps.check-creds.outputs.skip != 'true'
run: |
wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt \
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list \
https://files.pvs-studio.com/etc/viva64.list
sudo apt-get update
sudo apt-get install -y pvs-studio
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
- name: Download compilation database
if: steps.check-creds.outputs.skip != 'true'
uses: actions/download-artifact@v8
with:
name: compilation-database
- name: Generate build artifacts required for analysis
if: steps.check-creds.outputs.skip != 'true'
run: |
python3 scripts/generate-emoji-table.py \
Sources_Common/i18n/Charsets/CEmojiTable.h \
/usr/share/unicode/cldr/common/annotations/en.xml \
/usr/share/unicode/cldr/common/annotationsDerived/en.xml
mkdir -p Linux/Includes
cd Linux && bash links.sh && cd ..
mkdir -p Libraries/JX/include/jx Libraries/JX/include/jcore Libraries/JX/include/jximage
for f in Libraries/JX/libjx/code/*; do
ln -sf "../../libjx/code/$(basename "$f")" "Libraries/JX/include/jx/$(basename "$f")"
done
for f in Libraries/JX/libjcore/code/*; do
ln -sf "../../libjcore/code/$(basename "$f")" "Libraries/JX/include/jcore/$(basename "$f")"
done
for f in Libraries/JX/libjx/image/*; do
ln -sf "../../libjx/image/$(basename "$f")" "Libraries/JX/include/jximage/$(basename "$f")"
done
ln -sf config-linux.h Libraries/JX/ACE/ACE_wrappers/ace/config.h
ln -sf ../include/make/sys/Linux-Intel-x86_64-gcc3 Libraries/JX/include/make/jx_config
- name: Run PVS-Studio analysis
if: steps.check-creds.outputs.skip != 'true'
run: |
pvs-studio-analyzer analyze -f compile_commands.json -j \
-e Libraries/JX/ \
-e Libraries/vendor/ \
-e Libraries/vzic/ \
-e Libraries/include/ \
-e Libraries/openssl/
- name: Convert results to SARIF
if: steps.check-creds.outputs.skip != 'true'
run: |
plog-converter PVS-Studio.log \
-t json -n relative -R toRelative -r "$PWD"
plog-converter relative.json \
-t sarif -n pvs-report -r file://
- name: Upload SARIF to GitHub Security
if: steps.check-creds.outputs.skip != 'true'
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: pvs-report.sarif
category: PVS-Studio
continue-on-error: true
# ============================================================
# SonarCloud: technical debt and quality tracking
# ============================================================
sonarcloud:
name: Analyze (SonarCloud)
needs: build
runs-on: ubuntu-latest
continue-on-error: true
permissions:
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
- name: Download compilation database
uses: actions/download-artifact@v8
with:
name: compilation-database
- name: Normalize compilation database paths
run: |
python3 -c "
import json, os
db = json.load(open('compile_commands.json'))
changed = 0
for entry in db:
d = entry.get('directory', '')
f = entry.get('file', '')
resolved = os.path.normpath(os.path.join(d, f))
if resolved != f:
changed += 1
entry['file'] = resolved
if d:
entry['directory'] = os.path.normpath(d)
json.dump(db, open('compile_commands.json', 'w'), indent=2)
print(f'Normalized {len(db)} entries ({changed} paths resolved)')
"
- name: SonarCloud scan
uses: SonarSource/sonarqube-scan-action@v8
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
--define sonar.cfamily.compile-commands=compile_commands.json
- name: Export SonarCloud issues to SARIF
if: success()
run: python3 scripts/sonarcloud-to-sarif.py
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Upload SonarCloud SARIF
if: success()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: sonarcloud.sarif
category: sonarcloud
# ============================================================
# OSV-Scanner: dependency CVE scanning (git submodules)
# ============================================================
osv-scanner:
name: Dependency CVE Scan (OSV)
uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v2.3.8
permissions:
actions: read
contents: read
security-events: write
with:
scan-args: "-r ./ --allow-no-lockfiles"
checkout-submodules: true
fail-on-vuln: false