Revision control

Copy as Markdown

Other Tools

name: Install NSS
description: Install NSS
inputs:
minimum-version:
description: "Minimum required version of NSS"
required: true
target:
description: "Target for cross-compilation"
default: ""
runs:
using: composite
steps:
- name: Install system NSS (Linux)
shell: bash
if: ${{ runner.os == 'Linux' && inputs.target == '' && (runner.environment != 'self-hosted' || contains(runner.name, 'CodSpeed')) }}
env:
DEBIAN_FRONTEND: noninteractive
run: |
[ "$APT_UPDATED" ] || sudo apt-get update && echo "APT_UPDATED=1" >> "$GITHUB_ENV"
sudo apt-get install -y --no-install-recommends libnss3-dev
- name: Install system NSS (MacOS)
shell: bash
if: ${{ runner.os == 'MacOS' && inputs.target == '' }}
run: |
[ "$BREW_UPDATED" ] || brew update && echo "BREW_UPDATED=1" >> "$GITHUB_ENV"
brew install nss
- name: Check system NSS version
id: system_nss
env:
MIN_VERSION: ${{ inputs.minimum-version }}
shell: bash
if: inputs.target == ''
run: |
if ! pkg-config --atleast-version "$MIN_VERSION" nss; then
echo -n "System NSS needs ${MIN_VERSION}, got "
pkg-config --modversion nss 2>/dev/null || echo "pkg-config error"
exit 0
fi
echo "System NSS is suitable: $NSS_VERSION"
echo "suitable=1" >> "$GITHUB_OUTPUT"
- name: Use sccache
# Apparently the action can't be installed twice in the same workflow, so check if
# it's already installed by checking if the SCCACHE_ENABLED environment variable is set
# (which every "use" of this action needs to therefore set)
#
# Also, only enable sscache on our self-hosted runner, because the GitHub cache limit
# is too small for this to be effective there.
if: ${{ env.SCCACHE_ENABLED != '1' && !steps.system_nss.outputs.suitable && runner.environment == 'self-hosted' && !contains(runner.name, 'CodSpeed') }}
uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
- name: Enable sscache
if: ${{ !steps.system_nss.outputs.suitable && runner.environment == 'self-hosted' && !contains(runner.name, 'CodSpeed') }}
env:
RUNNER_ENVIRONMENT: ${{ runner.environment }}
RUNNER_OS: ${{ runner.os }}
shell: bash
run: |
echo "SCCACHE_ENABLED=1" >> "$GITHUB_ENV"
if [ "$RUNNER_OS" != "Windows" ]; then
# TODO: Figure out how to make this work on Windows
echo "SCCACHE_CC=sccache cc" >> "$GITHUB_ENV"
echo "SCCACHE_CXX=sccache c++" >> "$GITHUB_ENV"
fi
echo "CMAKE_C_COMPILER_LAUNCHER=sccache" >> "$GITHUB_ENV"
echo "CMAKE_CXX_COMPILER_LAUNCHER=sccache" >> "$GITHUB_ENV"
echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV"
- name: Retrieve NSS
id: nss
if: ${{ !steps.system_nss.outputs.suitable }}
shell: bash
env:
NSS_VERSION: "3.120" # TODO: Bump this periodically; also in qns/Dockerfile. Trailing zeroes are stripped w/o quotes!
run: |
NSS_TAG="${NSS_VERSION//./_}"
echo "Retrieving NSS $NSS_VERSION from $NSS_URL"
curl -L "$NSS_URL" | tar xz --strip-components=1
echo "version=$NSS_VERSION" >> "$GITHUB_OUTPUT"
- name: Retrieve NSPR
id: nspr
if: ${{ !steps.system_nss.outputs.suitable }}
shell: bash
env:
NSPR_VERSION: "4.38.2" # TODO: Bump this periodically; also in qns/Dockerfile. Trailing zeroes are stripped w/o quotes!
run: |
echo "Retrieving NSPR $NSPR_VERSION from $NSPR_URL"
curl -L "$NSPR_URL" | tar xz --strip-components=1
echo "version=$NSPR_VERSION" >> "$GITHUB_OUTPUT"
- name: Store Ubuntu release code name (Linux)
id: ubuntu_release
shell: bash
if: ${{ runner.os == 'Linux' && !steps.system_nss.outputs.suitable }}
run: |
# Store Ubuntu release codename for use in cache key.
. /etc/os-release
echo "codename=-$UBUNTU_CODENAME" >> "$GITHUB_OUTPUT"
# Use restore-only here so PRs don't create redundant caches. PRs restore
# from main; only main saves new caches. This reduces churn and evictions.
# Downside: PRs that change NSS version/build will rebuild on every CI run.
- name: Restore NSS cache
id: cache
if: ${{ !steps.system_nss.outputs.suitable }}
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: dist
key: nss-${{ inputs.target || runner.os }}${{ steps.ubuntu_release.outputs.codename }}-${{ runner.arch }}-${{ steps.nss.outputs.version }}-${{ steps.nspr.outputs.version }}
- name: Check if build is needed
id: check_build
if: ${{ !steps.system_nss.outputs.suitable }}
env:
CACHE_HIT: ${{ steps.cache.outputs.cache-hit }}
shell: bash
run: |
if [ "$CACHE_HIT" != "true" ]; then
echo "Building NSS from source"
echo "build_nss=1" >> "$GITHUB_OUTPUT"
else
echo "Using cached prebuilt NSS"
fi
- name: Install build dependencies (Linux)
shell: bash
if: ${{ runner.os == 'Linux' && steps.check_build.outputs.build_nss && (runner.environment != 'self-hosted' || contains(runner.name, 'CodSpeed')) }}
env:
DEBIAN_FRONTEND: noninteractive
run: sudo apt-get install -y --no-install-recommends gyp ninja-build
- name: Install build dependencies (MacOS)
shell: bash
if: ${{ runner.os == 'MacOS' && steps.check_build.outputs.build_nss }}
run: |
brew install ninja
echo "gyp-next>=0.18.1" > req.txt
python3 -m pip install --break-system-packages -r req.txt
- name: Install build dependencies (Windows)
shell: bash
if: ${{ runner.os == 'Windows' && steps.check_build.outputs.build_nss }}
run: |
# shellcheck disable=SC2028
{
echo C:/msys64/usr/bin
echo C:/msys64/mingw64/bin
} >> "$GITHUB_PATH"
/c/msys64/usr/bin/pacman -S --noconfirm python3-pip nsinstall
echo "gyp-next>=0.18.1" > req.txt
python3 -m pip install -r req.txt
- name: Set up MSVC (Windows)
if: ${{ runner.os == 'Windows' && steps.check_build.outputs.build_nss }}
uses: ilammy/msvc-dev-cmd@v1 # zizmor: ignore[unpinned-uses]
# TODO: Would like to pin this, but the Mozilla org allowlist requires "ilammy/msvc-dev-cmd@v1*"
# uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Set up build environment (Windows)
shell: bash
if: ${{ runner.os == 'Windows' && steps.check_build.outputs.build_nss }}
run: |
{
echo "GYP_MSVS_OVERRIDE_PATH=$VSINSTALLDIR"
echo "GYP_MSVS_VERSION=2022"
echo "BASH=$SHELL"
} >> "$GITHUB_ENV"
rm /usr/bin/link.exe || true
- name: Set up environment
shell: bash
if: ${{ !steps.system_nss.outputs.suitable }}
env:
NSS_DIR: ${{ github.workspace }}/nss
RUNNER_OS: ${{ runner.os }}
WORKSPACE: ${{ github.workspace }}
run: | # zizmor: ignore[github-env] We need to write to GITHUB_PATH on Windows.
NSS_OUT="$WORKSPACE/dist/Release"
{
echo "LD_LIBRARY_PATH=$NSS_OUT/lib"
echo "DYLD_FALLBACK_LIBRARY_PATH=$NSS_OUT/lib"
echo "NSS_DIR=$NSS_DIR"
echo "NSS_PREBUILT=1"
} >> "$GITHUB_ENV"
if [ "$RUNNER_OS" == "Windows" ]; then
echo "$NSS_OUT/lib" >> "$GITHUB_PATH"
fi
- name: Build
shell: bash
if: ${{ steps.check_build.outputs.build_nss }}
env:
TARGET_PLATFORM: ${{ inputs.target }}
RUNNER_OS: ${{ runner.os }}
run: |
# We want to do an optimized build for accurate CPU profiling, but
# we also want debug symbols and frame pointers for that, which the normal optimized NSS
# build process doesn't provide.
[ "$RUNNER_OS" != "Windows" ] && export CFLAGS="-ggdb3 -fno-omit-frame-pointer"
if [[ $TARGET_PLATFORM == *-android* ]]; then
for file in build-nss-android.sh build-android-common.sh; do
chmod +x "$file"
done
ANDROID_NDK_VERSION=$(basename "$ANDROID_NDK" | cut -d. -f1)
# It figures that NSPR would require monkey-patching to build on Android.
sed -i'' 's/if test -z "$android_ndk" ; then/$as_echo "#define ANDROID 1" >>confdefs.h\n ;;\nunreachable)\n if test -z "$android_ndk" ; then/g' nspr/configure
./build-nss-android.sh "$(pwd)" "/tmp/dist" "$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64" "$TARGET_PLATFORM" "$ANDROID_NDK_VERSION"
# Manually move the temporary build directory to the final location, which is what neqo-crypto expects.
find /tmp/tmp.* > tmp
CERTUTIL="$(grep certutil tmp)"
TARGET_DIR="$(dirname $(dirname $CERTUTIL))"
mkdir -p "dist/Release"
cp -vaL "$TARGET_DIR"/* "dist/Release/"
NSPR_H="$(grep nspr.h tmp)"
INCLUDE_DIR="$(dirname $NSPR_H)"
mkdir -p "dist/Release/include/nspr"
cp -vaL "$INCLUDE_DIR"/* "dist/Release/include/nspr"
CHACHA="$(grep chacha20poly1305.h tmp)"
PRIVATE_DIR="$(dirname $(dirname $CHACHA))"
mkdir -p "dist/private"
cp -vaL "$PRIVATE_DIR"/* "dist/private/"
UTILRENAME="$(grep utilrename.h tmp)"
PUBLIC_DIR="$(dirname $(dirname $(dirname $UTILRENAME)))"
mkdir -p "dist/public"
cp -vaL "$PUBLIC_DIR"/* "dist/"
LIBNSPR4="$(grep lib/libnspr4.a tmp)"
LIB_DIR="$(dirname $LIBNSPR4)"
mkdir -p "dist/Release/lib"
cp -vaL "$LIB_DIR"/* "dist/Release/lib"
else
[ "$SCCACHE_CC" ] && [ "$SCCACHE_CXX" ] && export CC="$SCCACHE_CC" CXX="$SCCACHE_CXX"
$NSS_DIR/build.sh -g -Ddisable_tests=1 -Ddisable_dbm=1 -Ddisable_libpkix=1 -Ddisable_ckbi=1 -Ddisable_fips=1 --opt --static
fi
- name: Save NSS cache
if: ${{ steps.check_build.outputs.build_nss && github.event_name != 'pull_request' }}
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: dist
key: nss-${{ inputs.target || runner.os }}${{ steps.ubuntu_release.outputs.codename }}-${{ runner.arch }}-${{ steps.nss.outputs.version }}-${{ steps.nspr.outputs.version }}