Skip to content

Suppress warning

Suppress warning #2097

Workflow file for this run

name: Build
on: [push, pull_request]
env:
QT_VERSION: 6.7.0
QT_MODULES: qtwebengine qtwebchannel qtpositioning
GCC_VERSION: 13
CLANG_VERSION: 17
jobs:
linux:
name: Linux
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt install gcc-${{ env.GCC_VERSION }} g++-${{ env.GCC_VERSION }}
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt install libxcb-cursor0
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }} qtserialport
cache: true
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: linux
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Compile
run: scripts/linux-build.sh
env:
CC: gcc-${{ env.GCC_VERSION }}
CXX: g++-${{ env.GCC_VERSION }}
- name: AppImage
run: |
installers/linux/build.sh
env:
CC: gcc-${{ env.GCC_VERSION }}
CXX: g++-${{ env.GCC_VERSION }}
- uses: actions/upload-artifact@v3
if: github.event_name != 'pull_request'
with:
name: Linux AppImage
path: build/gcc/Graphia-*.tar.gz
- uses: actions/upload-artifact@v3
with:
name: Linux Logs
path: build/gcc/*.log
- name: Upload Symbols
if: github.event_name != 'pull_request'
run: scripts/upload-symbols.sh
shell: bash
env:
SYM_UPLOAD_URL: ${{ secrets.SYM_UPLOAD_URL }}
windows:
name: Windows
runs-on: windows-2019
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
variant: sccache
key: windows
- uses: ilammy/msvc-dev-cmd@v1
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Compile
shell: cmd
run: call scripts\windows-build.bat
env:
CC: cl.exe
CXX: cl.exe
- name: NSIS Installer
shell: cmd
run: call installers\windows\build.bat
env:
CRTDIRECTORY: ${{ env.VcToolsRedistDir }}\x64\Microsoft.VC142.CRT
WINDOWS_SIGN_KEYSTORE_BASE64: ${{ secrets.WINDOWS_SIGN_KEYSTORE_BASE64 }}
WINDOWS_SIGN_PASSWORD: ${{ secrets.WINDOWS_SIGN_PASSWORD }}
WINDOWS_SIGN_SUBJECTNAME: ${{ secrets.WINDOWS_SIGN_SUBJECTNAME }}
WINDOWS_SIGN_TSA: ${{ secrets.WINDOWS_SIGN_TSA }}
- uses: actions/upload-artifact@v3
if: github.event_name != 'pull_request'
with:
name: Windows Installer
path: build/Graphia-*-installer.exe
- uses: actions/upload-artifact@v3
with:
name: Windows Logs
path: build/*.log
- name: Upload Symbols
if: github.event_name != 'pull_request'
run: scripts/upload-symbols.sh
shell: bash
env:
SYM_UPLOAD_URL: ${{ secrets.SYM_UPLOAD_URL }}
macos:
name: macOS
runs-on: macos-13
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Force Python to version 3.10 to workaround node-gyp install problem (remove later)
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
setup-python: false # Python installed above
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: macos
- uses: seanmiddleditch/gha-setup-ninja@v3
- uses: actions/setup-node@v3
with:
node-version: '12'
- name: Compile
run: scripts/macos-build.sh
- name: app and dmg
run: |
npm install -g appdmg
installers/macos/build.sh
env:
APPLE_CERTIFICATE_P12_BASE64: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_SIGN_ID: ${{ secrets.APPLE_SIGN_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- uses: actions/upload-artifact@v3
if: github.event_name != 'pull_request'
with:
name: macOS Disk Image
path: build/Graphia-*.dmg
- uses: actions/upload-artifact@v3
with:
name: macOS Logs
path: build/*.log
- name: Upload Symbols
if: github.event_name != 'pull_request'
run: scripts/upload-symbols.sh
shell: bash
env:
SYM_UPLOAD_URL: ${{ secrets.SYM_UPLOAD_URL }}
wasm:
name: WebAssembly
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Determine appropriate emsdk version
run: |
EMSDK_VERSION=$(scripts/emsdk-version-for-qt-version.sh ${{ env.QT_VERSION }})
echo "EMSDK_VERSION=${EMSDK_VERSION}" >> $GITHUB_ENV
- name: Install emsdk
uses: mymindstorm/setup-emsdk@v13
with:
version: ${{ env.EMSDK_VERSION }}
- name: Install Qt
uses: timangus/install-qt-action@deployed
with:
aqtsource: git+https://github.com/timangus/aqtinstall.git
version: ${{ env.QT_VERSION }}
host: all_os
target: wasm
arch: wasm_multithread
extra: --autodesktop
cache: true
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: wasm
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Compile
run: |
scripts/wasm-build.sh
env:
UNITY_BUILD: OFF
- name: Deploy
run: |
installers/wasm/build.sh
- uses: actions/upload-artifact@v3
if: github.event_name != 'pull_request'
with:
name: WebAssembly
path: build/wasm/Graphia-*
- uses: actions/upload-artifact@v3
with:
name: WebAssembly Logs
path: build/wasm/*.log
clang-debug:
name: Clang Debug
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
sudo bash /tmp/llvm.sh ${{ env.CLANG_VERSION }}
sudo apt-get update
sudo apt-get install libc++-${{ env.CLANG_VERSION }}-dev libc++1-${{ env.CLANG_VERSION }} libc++abi-${{ env.CLANG_VERSION }}-dev libc++abi1-${{ env.CLANG_VERSION }}
sudo apt-get install libunwind-${{ env.CLANG_VERSION }}-dev
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: clang-debug
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Compile
run: |
scripts/linux-build.sh
scripts/parse-compile_commands-json.sh
env:
BUILD_TYPE: Debug
UNITY_BUILD: OFF
CC: clang-${{ env.CLANG_VERSION }}
CXX: clang++-${{ env.CLANG_VERSION }}
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Build
path: |
build/clang/variables.sh
build/clang/compile_commands.json
build/clang/**/*.h
build/clang/**/*.hpp
build/clang/**/*.hxx
build/clang/**/*.c
build/clang/**/*.cpp
build/clang/**/*.cxx
windows-clang:
name: Windows Clang
runs-on: windows-2019
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
variant: sccache
key: windows-clang
- uses: ilammy/msvc-dev-cmd@v1
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Compile
shell: cmd
run: call scripts\windows-build.bat
env:
CC: clang-cl.exe
CXX: clang-cl.exe
- name: NSIS Installer
shell: cmd
run: call installers\windows\build.bat
env:
CRTDIRECTORY: ${{ env.VcToolsRedistDir }}\x64\Microsoft.VC142.CRT
WINDOWS_SIGN_KEYSTORE_BASE64: ${{ secrets.WINDOWS_SIGN_KEYSTORE_BASE64 }}
WINDOWS_SIGN_PASSWORD: ${{ secrets.WINDOWS_SIGN_PASSWORD }}
WINDOWS_SIGN_SUBJECTNAME: ${{ secrets.WINDOWS_SIGN_SUBJECTNAME }}
WINDOWS_SIGN_TSA: ${{ secrets.WINDOWS_SIGN_TSA }}
- uses: actions/upload-artifact@v3
if: github.event_name != 'pull_request'
with:
name: Windows Clang Installer
path: build/Graphia-*-installer.exe
- uses: actions/upload-artifact@v3
with:
name: Windows Clang Logs
path: build/*.log
- name: Upload Symbols
if: github.event_name != 'pull_request'
run: scripts/upload-symbols.sh
shell: bash
env:
SYM_UPLOAD_URL: ${{ secrets.SYM_UPLOAD_URL }}
clang-tidy:
name: Clang-Tidy
runs-on: ubuntu-latest
needs:
- clang-debug
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
sudo bash /tmp/llvm.sh ${{ env.CLANG_VERSION }}
sudo apt-get update
sudo apt-get install libc++-${{ env.CLANG_VERSION }}-dev libc++1-${{ env.CLANG_VERSION }} libc++abi-${{ env.CLANG_VERSION }}-dev libc++abi1-${{ env.CLANG_VERSION }}
sudo apt-get install libunwind-${{ env.CLANG_VERSION }}-dev
sudo apt-get install clang-tidy-${{ env.CLANG_VERSION }}
- name: Checkout ctcache
uses: actions/checkout@v3
with:
repository: matus-chochlik/ctcache
path: ctcache
- name: Install ctcache
run: |
sudo mv ctcache /opt/ctcache
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
shell: bash
- name: Store ctcache
uses: actions/cache@v3
with:
key: ctcache-${{ steps.get-date.outputs.date }}
path: /tmp/clang-tidy-cache
restore-keys: |
ctcache-
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- uses: actions/download-artifact@v3
with:
name: Static Analysis Build
path: build/clang/
- name: Analyse
run: scripts/clang-tidy.sh
env:
CLANGTIDY: /opt/ctcache/clang-tidy
CTCACHE_DIR: /tmp/clang-tidy-cache
CTCACHE_CLANG_TIDY: clang-tidy-${{ env.CLANG_VERSION }}
CTCACHE_SAVE_OUTPUT: 1
BUILD_DIR: build/clang/
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
cppcheck:
name: cppcheck
runs-on: ubuntu-latest
needs:
- clang-debug
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
sudo bash /tmp/llvm.sh ${{ env.CLANG_VERSION }}
sudo apt-get update
sudo apt-get install libc++-${{ env.CLANG_VERSION }}-dev libc++1-${{ env.CLANG_VERSION }} libc++abi-${{ env.CLANG_VERSION }}-dev libc++abi1-${{ env.CLANG_VERSION }}
sudo apt-get install libunwind-${{ env.CLANG_VERSION }}-dev
sudo apt-get update
sudo apt-get install cppcheck
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- uses: actions/download-artifact@v3
with:
name: Static Analysis Build
path: build/clang/
- name: Analyse
run: scripts/cppcheck.sh
env:
CPPCHECK: cppcheck
BUILD_DIR: build/clang/
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
clazy:
name: Clazy
runs-on: ubuntu-latest
needs:
- clang-debug
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
sudo bash /tmp/llvm.sh ${{ env.CLANG_VERSION }}
sudo apt install g++ cmake clang llvm-${{ env.CLANG_VERSION }}-dev git-core libclang-${{ env.CLANG_VERSION }}-dev
sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${{ env.CLANG_VERSION }} 100
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- uses: actions/checkout@v3
with:
repository: KDE/clazy
path: clazy
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: clazy
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Build clazy
run: |
cd clazy/
sed -i 's/target_precompile_headers/#target_precompile_headers/' CMakeLists.txt
cmake -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -G Ninja
cmake --build .
sudo cmake --build . --target install
- uses: actions/download-artifact@v3
with:
name: Static Analysis Build
path: build/clang/
- name: Analyse
run: scripts/clazy.sh
env:
CLAZY: /usr/bin/clazy
BUILD_DIR: build/clang/
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
qmllint:
name: QML Lint
runs-on: ubuntu-latest
needs:
- clang-debug
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- uses: actions/download-artifact@v3
with:
name: Static Analysis Build
path: build/clang/
- name: Analyse
run: scripts/qmllint.sh
env:
BUILD_DIR: build/clang/
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
iwyu:
name: Include What You Use
runs-on: ubuntu-latest
needs:
- clang-debug
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Install Tools
run: |
sudo wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
sudo bash /tmp/llvm.sh ${{ env.CLANG_VERSION }}
sudo apt install g++ cmake clang llvm-${{ env.CLANG_VERSION }}-dev git-core libclang-${{ env.CLANG_VERSION }}-dev
sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${{ env.CLANG_VERSION }} 100
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
modules: ${{ env.QT_MODULES }}
cache: true
- uses: actions/checkout@v3
with:
repository: include-what-you-use/include-what-you-use
ref: clang_${{ env.CLANG_VERSION }}
path: iwyu
- name: ccache
uses: hendrikmuhs/ccache-action@main
with:
key: iwyu
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Build IWYU
run: |
cd iwyu/
cmake -DCMAKE_PREFIX_PATH=/usr/lib/llvm-${{ env.CLANG_VERSION }} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -G Ninja
cmake --build .
sudo cmake --build . --target install
- uses: actions/download-artifact@v3
with:
name: Static Analysis Build
path: build/clang/
- name: Analyse
run: scripts/iwyu.sh
env:
BUILD_DIR: build/clang/
IWYU_SOURCE: ${{ github.workspace }}/iwyu
- uses: actions/upload-artifact@v3
with:
name: Static Analysis Logs
path: build/clang/*.log
check-is-release:
if: github.event_name != 'pull_request'
name: Check For Release Tag
runs-on: ubuntu-latest
outputs:
is-release: ${{ steps.is-release-test.outputs.result }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Check Release Tag
id: is-release-test
run: |
GIT_TAG=$(git describe --exact-match --tags || true)
if [[ -z "${GIT_TAG}" || "${{ github.ref_type }}" != 'tag' ]]
then
echo "Not tagged"
echo "result=false" >> $GITHUB_OUTPUT
elif [[ "${GIT_TAG}" =~ ^[0-9]+\.[0-9]+(-rc[0-9]+)?$ ]]
then
echo "'${GIT_TAG}' is a release"
echo "result=true" >> $GITHUB_OUTPUT
else
echo "'${GIT_TAG}' is not a release"
echo "result=false" >> $GITHUB_OUTPUT
fi
shell: bash
release:
name: GitHub Release
if: github.event_name != 'pull_request' && needs.check-is-release.outputs.is-release == 'true'
runs-on: ubuntu-latest
needs:
- check-is-release
- linux
- windows
- macos
steps:
- uses: actions/download-artifact@v3
with:
name: Linux AppImage
path: release/Linux AppImage
- uses: actions/download-artifact@v3
with:
name: macOS Disk Image
path: release/macOS Disk Image
- uses: actions/download-artifact@v3
with:
name: Windows Installer
path: release/Windows Installer
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
- name: Upload Binaries
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: release/*/*
tag: ${{ github.ref }}
overwrite: true
file_glob: true
prereleasebuilds:
if: github.event_name != 'pull_request'
name: Upload Builds to graphia.dev
runs-on: ubuntu-latest
needs:
- linux
- windows
- macos
- wasm
- windows-clang
steps:
- uses: actions/download-artifact@v3
with:
name: Linux AppImage
path: prerelease/Linux AppImage
- uses: actions/download-artifact@v3
with:
name: Linux Logs
path: prerelease/Linux Logs
- uses: actions/download-artifact@v3
with:
name: macOS Disk Image
path: prerelease/macOS Disk Image
- uses: actions/download-artifact@v3
with:
name: macOS Logs
path: prerelease/macOS Logs
- uses: actions/download-artifact@v3
with:
name: Windows Installer
path: prerelease/Windows Installer
- uses: actions/download-artifact@v3
with:
name: Windows Logs
path: prerelease/Windows Logs
- uses: actions/download-artifact@v3
with:
name: Windows Clang Installer
path: prerelease/Windows Clang Installer
- uses: actions/download-artifact@v3
with:
name: Windows Clang Logs
path: prerelease/Windows Clang Logs
- uses: actions/download-artifact@v3
with:
name: WebAssembly
path: prerelease/WebAssembly
- uses: actions/download-artifact@v3
with:
name: WebAssembly Logs
path: prerelease/WebAssembly Logs
- uses: horochx/deploy-via-scp@master
with:
host: ${{ secrets.PRERELEASE_HOST }}
user: ${{ secrets.PRERELEASE_USERNAME }}
key: ${{ secrets.PRERELEASE_KEY }}
local: "prerelease/*"
remote: ${{ secrets.PRERELEASE_DIR }}
prereleasestaticanalysislogs:
if: github.event_name != 'pull_request'
name: Upload Logs to graphia.dev
runs-on: ubuntu-latest
needs:
- clang-debug
- clang-tidy
- cppcheck
- clazy
- iwyu
- qmllint
steps:
- uses: actions/download-artifact@v3
with:
name: Static Analysis Logs
path: prerelease/Static Analysis Logs
- uses: horochx/deploy-via-scp@master
with:
host: ${{ secrets.PRERELEASE_HOST }}
user: ${{ secrets.PRERELEASE_USERNAME }}
key: ${{ secrets.PRERELEASE_KEY }}
local: "prerelease/*"
remote: ${{ secrets.PRERELEASE_DIR }}
log-analysis:
if: github.event_name != 'pull_request'
name: Analyse Logs
runs-on: ubuntu-latest
needs:
- linux
- windows
- macos
- wasm
- clang-debug
- windows-clang
- clang-tidy
- cppcheck
- clazy
- qmllint
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
fetch-depth: 0
- uses: actions/download-artifact@v3
with:
name: Linux Logs
path: logs/linux
- uses: actions/download-artifact@v3
with:
name: macOS Logs
path: logs/macos
- uses: actions/download-artifact@v3
with:
name: Windows Logs
path: logs/windows
- uses: actions/download-artifact@v3
with:
name: Windows Clang Logs
path: logs/windows-clang
- uses: actions/download-artifact@v3
with:
name: WebAssembly Logs
path: logs/wasm
- uses: actions/download-artifact@v3
with:
name: Static Analysis Logs
path: logs/staticanalysis
- name: Install Perl modules
uses: perl-actions/install-with-cpanm@v1
with:
install: |
Text::Table::CSV
Text::Table::Tiny
- name: Analyse
run: |
SHORT_SHA=$(git rev-parse --short HEAD)
MESSAGE=$(git log --format=%B -n1 HEAD | head -n1)
BRANCH=$(echo ${GITHUB_REF#refs/*/})
eval "$(ssh-agent -s)"
echo "${{ secrets.DEFECTS_SSH_PRIVATE_KEY }}" | ssh-add -
git config --global user.email ""
git config --global user.name "Log Analyser"
git clone [email protected]:graphia-app/defects.git defects
cd defects
./update.sh -b $BRANCH -l "../logs" -m "$SHORT_SHA $MESSAGE"