Skip to content
Draft
24 changes: 16 additions & 8 deletions .github/workflows/root-ci-config/build_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def main():
build_utils.print_warning(f'Failed to download: {err}')
args.incremental = False

git_pull("src", args.repository, args.base_ref)
if not args.source_dir:
git_pull("src", args.repository, args.base_ref)

benchmark: bool = 'rootbench' in options_dict and options_dict['rootbench'] == "ON"
if benchmark:
Expand All @@ -166,7 +167,10 @@ def main():
# Delete all the .gcda files produces by an artefact.
build_utils.remove_file_match_ext(WORKDIR, "gcda")

build(options, args.buildtype)
if args.source_dir:
build(options, args.buildtype, source_dir=args.source_dir)
else:
build(options, args.buildtype)

# Build artifacts should only be uploaded for full builds, and only for
# "official" branches (master, v?-??-??-patches), i.e. not for pull_request
Expand Down Expand Up @@ -227,6 +231,7 @@ def parse_args():
parser.add_argument("--pull_repository", default="", help="Url to the pull request incoming repository")
parser.add_argument("--head_ref", default=None, help="Ref to feature branch; it may contain a :<dst> part")
parser.add_argument("--head_sha", default=None, help="Sha of commit that triggered the event")
parser.add_argument("--source_dir", default=None, help="Don't check out. Just use the source dir provided here.")
parser.add_argument("--binaries", default="false", help="Whether to create binary artifacts")
parser.add_argument("--architecture", default=None, help="Windows only, target arch")
parser.add_argument("--repository", default="https://github.com/root-project/root.git",
Expand All @@ -242,7 +247,7 @@ def parse_args():
args.binaries = args.binaries.lower() in ('yes', 'true', '1', 'on')
args.upload_artifacts = args.upload_artifacts.lower() in ('yes', 'true', '1', 'on')

if not args.base_ref:
if not args.base_ref and not args.source_dir:
die(os.EX_USAGE, "base_ref not specified")

if not args.platform_config: # If nothing special, we take the standard platform configuration, called as the platform
Expand Down Expand Up @@ -396,8 +401,11 @@ def archive_and_upload(archive_name, prefix):


@github_log_group("Configure")
def cmake_configure(options, buildtype):
srcdir = os.path.join(WORKDIR, "src")
def cmake_configure(options, buildtype, **kwargs):
if 'source_dir' in kwargs:
srcdir = kwargs['source_dir']
else:
srcdir = os.path.join(WORKDIR, "src")
builddir = os.path.join(WORKDIR, "build")

# Add a private option to make the CI build faster by not changing the
Expand Down Expand Up @@ -445,16 +453,16 @@ def cmake_build(buildtype):
die(result, "Failed to build")


def build(options, buildtype):
def build(options, buildtype, **kwargs):
if not os.path.isdir(os.path.join(WORKDIR, "build")):
builddir = os.path.join(WORKDIR, "build")
result = subprocess_with_log(f"mkdir {builddir}")
result = subprocess_with_log(f"mkdir -p {builddir}")

if result != 0:
die(result, "Failed to create build directory")

if not os.path.exists(os.path.join(WORKDIR, "build", "CMakeCache.txt")):
cmake_configure(options, buildtype)
cmake_configure(options, buildtype, **kwargs)
else:
cmake_dump_config()

Expand Down
200 changes: 75 additions & 125 deletions .github/workflows/root-docs-ci.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
name: 'ROOT Docs CI'

on:
pull_request:
paths:
- '.github/workflows/root-docs-ci.yml'
- 'documentation/doxygen/**'
branches:
- 'master'

# Allows nightly builds to trigger one run for each branch easily, by
# providing the relevant branch as "default" value here:
workflow_call:
inputs:
incremental:
type: boolean
default: true

workflow_dispatch:
inputs:
incremental:
description: 'Do full build'
type: boolean
eos_upload_directory:
description: 'Make documentation available at <root-website>/doc/<directory>. Leave empty for skipping the upload to eos.'
type: string
required: false
default: false
# docu_input: # opportunity: overwrite makeinput.sh with these args
# description: Folders to build documentation for. All folders are built if empty.
# type: string
# default: ""
# required: false
default: 'master'

env:
PLATFORM: alma10
DOC_DIR: ${{ case(github.base_ref == null, github.ref_name, 'PullRequest') }}
DOC_LOCATION: /github/home
EOS_DIR_NAME: |-
${{ case(
inputs.eos_upload_directory != null, inputs.eos_upload_directory,
github.base_ref != null, 'PR',
github.ref_name
)
}}
TAR_FILE: html${{ case(github.base_ref == null, github.ref_name, '_PullRequest') }}.tar.gz

jobs:
build-docs:
Expand All @@ -32,20 +40,14 @@ jobs:
- linux
- x64

env:
PLATFORM: alma9
DOC_DIR: master
DOC_LOCATION: /github/home
BASE_REF: master
WEB_DIR_NAME: master
TAR_NAME: htmlmaster.tar

permissions:
contents: read

container:
image: registry.cern.ch/root-ci/alma9:buildready
image: registry.cern.ch/root-ci/alma10:buildready
options: '--security-opt label=disable --rm'
volumes:
- alma10_ccache_volume:/github/home/.cache/ccache
env:
OS_APPLICATION_CREDENTIAL_ID: '7f5b64a265244623a3a933308569bdba'
OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
Expand All @@ -57,124 +59,69 @@ jobs:
PYTHONUNBUFFERED: true

steps:
- name: Prepare qhelpgenerator
# Qt6's libexec executables are not in the PATH by default
run: |
QHELPGENERATOR=$(which qhelpgenerator) && echo "QHELPGENERATOR=${QHELPGENERATOR}" >> "${GITHUB_ENV}"
PATH=/usr/lib64/qt6/libexec/:${PATH} QHELPGENERATOR=$(which qhelpgenerator) && echo "QHELPGENERATOR=${QHELPGENERATOR}" >> "${GITHUB_ENV}"

- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ env.BASE_REF }}
fetch-depth: 0

- name: Set up Python Virtual Env
# if the `if` expr is false, `if` still has exit code 0.
# if the `if` block is entered, the block's exit code becomes the exit
# code of the `if`.
run: 'if [ -d /py-venv/ROOT-CI/bin/ ]; then . /py-venv/ROOT-CI/bin/activate && echo PATH=$PATH >> $GITHUB_ENV; fi'

- name: Set up directory name and tar filenames
run: |
echo TAR_NAME=html${BASE_REF}.tar >> $GITHUB_ENV
echo DOCDIR_NAME=${BASE_REF} >> $GITHUB_ENV

# TODO: install latest versions in image on root-ci-images
- name: Install Doxygen 1.10.0
run : |
mkdir -p ${{ github.workspace }}/doxygen
curl -L https://github.com/doxygen/doxygen/releases/download/Release_1_10_0/doxygen-1.10.0.linux.bin.tar.gz | tar -xz -C ${{ github.workspace }}/doxygen/ --strip-components=1
echo PATH=$PATH:${{ github.workspace }}/doxygen/bin >> $GITHUB_ENV
# git clone --branch Release_1_12_0 https://github.com/doxygen/doxygen.git
# cd doxygen
# mkdir build
# cd build
# cmake ..
# make -j$(nproc)
# echo PATH=$PATH:${{ github.workspace }}/doxygen/build/bin >> $GITHUB_ENV
# cd ${{ github.workspace }}
# doxygen --version

- name: Install qhelpgenerator-qt5
run: |
dnf upgrade -y
dnf install -y qt5-doctools
which qhelpgenerator-qt5
run: 'if [ -d /py-venv/ROOT-CI/bin/ ]; then . /py-venv/ROOT-CI/bin/activate && echo ${PATH%:*} >> "${GITHUB_PATH}"; fi'

- name: Apply option overrides
env:
OVERRIDES: "testing=Off roottest=Off"
CONFIGFILE: '.github/workflows/root-ci-config/buildconfig/alma9.txt'
shell: bash
run: |
set -x
echo '' >> "$CONFIGFILE"
for ENTRY in $OVERRIDES; do
KEY=$( echo "$ENTRY" | cut -d '=' -f 1 )
# Add entry to file if not exists, otherwise replace
if grep -q "$KEY=" "$CONFIGFILE"; then
sed -i "s/$KEY=.*\$/$ENTRY/" "$CONFIGFILE"
else
echo "$ENTRY" >> "$CONFIGFILE"
fi
done
cat "$CONFIGFILE" || true

- name: Build ROOT - Workflow Dispatch
if: github.event_name == 'workflow_dispatch'
env:
INCREMENTAL: ${{ inputs.incremental == 'true' }}
- name: Build ROOT
run: ".github/workflows/root-ci-config/build_root.py
--buildtype Release
--platform ${{ env.PLATFORM }}
--incremental ${{ env.INCREMENTAL }}
--base_ref ${BASE_REF}
--head_ref ${BASE_REF}
--binaries false
--repository ${{ github.server_url }}/${{ github.repository }}"

- name: Build ROOT - Schedule
if: github.event_name == 'schedule'
run: ".github/workflows/root-ci-config/build_root.py
--buildtype Release
--platform ${{ env.PLATFORM }}
--incremental ${{ inputs.incremental }}
--base_ref ${BASE_REF}
--head_ref ${BASE_REF}
--binaries false
--repository ${{ github.server_url }}/${{ github.repository }}"
--incremental false
--source_dir ${GITHUB_WORKSPACE}
--repository ${{ github.server_url }}/${{ github.repository }}
--overrides testing=Off roottest=Off
--upload_artifacts false
--binaries false"

- name: Run Doxygen
working-directory: ${{ env.DOC_LOCATION }}
shell: bash
run: |
source ROOT-CI/build/bin/thisroot.sh
export DOXYGEN_OUTPUT_DIRECTORY=/github/home/${DOC_DIR}
cd ROOT-CI/src/documentation/doxygen
make -j `nproc --all`
source ${HOME}/ROOT-CI/build/bin/thisroot.sh
export DOXYGEN_OUTPUT_DIRECTORY="/github/home/${DOC_DIR}"
cd documentation/doxygen
make -j "$(nproc --all)"

- name: Clean temporary files
# These files are used when doxygen runs incrementally
shell: bash
run: |
cd "/github/home/${DOC_DIR}"
rm html/*.md5
rm html/*.map

- name: Create documentation archives
working-directory: ${{ env.DOC_LOCATION }}
shell: bash
run: |
pwd
ls -l
echo ${DOC_DIR}
echo ${TAR_NAME}
ls -l ${DOC_DIR}
tar cf ${TAR_NAME} ${DOC_DIR}
gzip ${TAR_NAME}
tar -caf ${TAR_FILE} ${DOC_DIR}
ls -l

#Upload to GitHub as an artifact
- name: Upload tar file for GH
- name: Upload tar file to github
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{env.TAR_NAME}}.gz
path: ${{env.DOC_LOCATION}}/${{env.TAR_NAME}}.gz
name: ${{env.TAR_FILE}}
path: ${{env.DOC_LOCATION}}/${{env.TAR_FILE}}
if-no-files-found: error

- name: Install Kerberos utilities
run: dnf -y install krb5-workstation

- name: Install XRootD client
run: dnf -y install xrootd-client
archive: false
retention-days: 8

- name: Sync documentation to EOS
env:
Expand All @@ -185,26 +132,29 @@ jobs:
EOS_BASE_PATH: /eos/project/r/root-eos/website/
EOS_ENDPOINT: root://eosproject-r.cern.ch
KRB5CCNAME: /tmp/krb5cc
if: ${{ env.KRB5REALM != '' && env.EOS_DIR_NAME != null && env.EOS_DIR_NAME != '' }}
working-directory: ${{ env.DOC_LOCATION }}
# Because of https://github.com/xrootd/xrootd/issues/2235 , the xrd client can copy
# only at most 65536 in one go. For this reason, we copy files in batches, dividing
# them by extension. Once that is fixed in XRootD, a single command can be used
# instead.
run: |
echo "Input eos directory: ${EOS_DIR_NAME}"
EOS_DIR_NAME="${EOS_DIR_NAME%-00-patches}"
EOS_DIR_NAME="${EOS_DIR_NAME/-/}"
echo "Uploading to the directory: ${EOS_DIR_NAME}"
failure=0
echo ${RWEBEOS_KT} | base64 -d > ${KT_FILE_NAME}
kinit -p ${{ secrets.KRB5USER }}@${{ secrets.KRB5REALM }} -kt ${KT_FILE_NAME}
cd ${DOC_DIR}/html/
rm -rf *.map # Intermediate files to create dot graphs
rm -rf *.md5 # As above
xrdcp --parallel 64 -rf ./*.html ${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${WEB_DIR_NAME} || failure=1
rm -rf *.html
xrdcp --parallel 64 -rf ./*.svg ${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${WEB_DIR_NAME} || failure=1
rm -rf *.svg
xrdcp --parallel 64 -rf ./ ${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${WEB_DIR_NAME} || failure=1
echo "${RWEBEOS_KT}" | base64 -d > "${KT_FILE_NAME}"
kinit -p ${{ secrets.KRB5USER }}@${{ secrets.KRB5REALM }} -kt "${KT_FILE_NAME}"
cd "${DOC_DIR}/html/"
xrdcp --parallel 64 -rf ./*.html "${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${EOS_DIR_NAME}" || failure=1
rm -rf ./*.html
xrdcp --parallel 64 -rf ./*.svg "${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${EOS_DIR_NAME}" || failure=1
rm -rf ./*.svg
xrdcp --parallel 64 -rf ./ "${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${EOS_DIR_NAME}" || failure=1
cd ..
rm -r html
xrdcp --parallel 64 -rf ./ ${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${WEB_DIR_NAME} || failure=1
xrdcp --parallel 64 -rf ./ "${EOS_ENDPOINT}/${EOS_BASE_PATH}/doc/${EOS_DIR_NAME}" || failure=1
cd ..
xrdcp -rf ${TAR_NAME}.gz ${EOS_ENDPOINT}/${EOS_BASE_PATH}/download || failure=1
exit $failure
xrdcp -rf "${TAR_FILE}" "${EOS_ENDPOINT}/${EOS_BASE_PATH}/download" || failure=1
exit "$failure"
2 changes: 1 addition & 1 deletion documentation/doxygen/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -1699,7 +1699,7 @@ QHP_SECT_FILTER_ATTRS =
# run qhelpgenerator on the generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.

QHG_LOCATION = qhelpgenerator-qt5
QHG_LOCATION = $(QHELPGENERATOR)

# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
Expand Down
3 changes: 3 additions & 0 deletions documentation/doxygen/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ doxygen: filter pyzdoc htmlfooter
$(call MkDir,$(DOXYGEN_EXAMPLE_PATH))
$(call MkDir,$(DOXYGEN_NOTEBOOK_PATH))
./makeinput.sh
echo "*** Diff of config file with default template:"
doxygen -x
echo "*** Run doxygen"
doxygen
bash ./CleanNamespaces.sh
gzip $(DOXYGEN_IMAGE_PATH)/ROOT.tag
Expand Down
4 changes: 2 additions & 2 deletions documentation/doxygen/converttonotebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def findBracedBlock(text, startpos, openingBraceChar):


def findStuffBeforeFunc(text, searchStart, searchEnd):
beforeFunctionRe = re.compile("(;|}|//[^\n]*)\s*$", flags = re.MULTILINE)
beforeFunctionRe = re.compile("(;|}|//[^\n]*)\\s*$", flags = re.MULTILINE)
try:
# Find the last '}' or comment line etc before function definition:
lastMatchBeforeFunc = [thisMatch for thisMatch in beforeFunctionRe.finditer(text, searchStart, searchEnd)][-1]
Expand Down Expand Up @@ -622,7 +622,7 @@ def changeString(matchObject):
matchString = matchString.replace("THISISASPACE" , " ")
return matchString

newcode = re.sub("#\s\s?\w\s[\w-]\s\w.*", changeString , code)
newcode = re.sub(r"#\s\s?\w\s[\w-]\s\w.*", changeString , code)
return newcode

def declareNamespace(code):
Expand Down
Loading