CI Workflow #1098
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: CI Workflow | |
on: | |
workflow_dispatch: | |
push: | |
branches: | |
- 'master' | |
repository_dispatch: | |
types: [build_documentation] | |
schedule: | |
- cron: '0 2 * * *' | |
jobs: | |
docs: | |
name: "Publish" | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@master | |
- name: Configure git and environment variables | |
run: | | |
# Configure git | |
git config --global push.default upstream | |
git config --global user.name "GitHub Actions" | |
git config --global user.email "[email protected]" | |
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git | |
# Fetch the yarp_it_pages branch on the yarp-documentation repository | |
git fetch origin yarp_it_pages 2>/dev/null || true | |
# Checkout yarp_it_pages branch on the yarp-documentation repository | |
git checkout --orphan yarp_it_pages | |
yarp_checkout_dir="${PWD}/yarp" | |
# Must end with "/" | |
yarp_url="www.yarp.it/" | |
yarp_url_re="$(echo ${yarp_url} | sed 's|www\.|(www\.)?|g' | sed 's|\.|\\\.|g' | sed 's|\/|\\\/|g')" | |
yarp_cname="$(echo ${yarp_url} | sed 's|/.*||g')" | |
# Set the variables so that they are available for the next steps | |
echo "YARP_CHECKOUT_DIR=${yarp_checkout_dir}" >> $GITHUB_ENV | |
echo "YARP_URL=${yarp_url}" >> $GITHUB_ENV | |
echo "YARP_URL_RE=${yarp_url_re}" >> $GITHUB_ENV | |
echo "YARP_CNAME=${yarp_cname}" >> $GITHUB_ENV | |
- name: Clone YARP repository and select branches and tags | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Clone YARP repository | |
git clone https://github.com/robotology/yarp.git ${YARP_CHECKOUT_DIR} | |
# Get list of all devices repositories | |
gh repo list robotology -L 1000 | grep -E 'yarp-device-|yarp-devices-' | cut -f 1 > yarp-device-list.txt | |
echo "Found the following devices repositories:" | |
cat yarp-device-list.txt | |
# Clone external devices dirs | |
yarpDeviceEntries=$(sed 's/.*\///' yarp-device-list.txt) | |
for yarpDeviceEntry in $yarpDeviceEntries | |
do | |
git clone --sparse https://github.com/robotology/${yarpDeviceEntry}.git ${YARP_CHECKOUT_DIR}/opt-modules/${yarpDeviceEntry} | |
cd ${YARP_CHECKOUT_DIR}/opt-modules/${yarpDeviceEntry} && git sparse-checkout set src/devices | |
done | |
#--- Beginning of robotology-playground repos | |
# # Clone external devices dirs | |
# git clone --sparse https://github.com/robotology-playground/yarp-devices-ros2.git ${YARP_CHECKOUT_DIR}/opt-modules/yarp-devices-ros2 | |
# cd ${YARP_CHECKOUT_DIR}/opt-modules/yarp-devices-ros2 && git sparse-checkout set src/devices | |
#--- End of robotology-playground repos | |
# Git branches. | |
# For now generate documentation just for the "master" branch. | |
branches="master" | |
echo -e "Selected branches:\n${branches}\n" | |
# Get all git tags and keep only the last tag for each series | |
all_tags=$(git -C ${YARP_CHECKOUT_DIR} for-each-ref --format="%(refname)" refs/tags/v* | grep -v "v1\|v2" | sed "s#refs/tags/##" | sort -V) | |
unset tags | |
unset cur_vmaj | |
unset cur_vmin | |
unset cur_tag | |
for tag in ${all_tags}; do | |
vmaj=$(echo ${tag} | sed 's/v//' | cut -d'.' -f1) | |
vmin=$(echo ${tag} | sed 's/v//' | cut -d'.' -f2) | |
if [ "${cur_vmaj}.${cur_vmin}" != "${vmaj}.${vmin}" ]; then | |
if [ -n "${cur_tag}" ]; then | |
tags="${tags}${cur_tag}"$'\n' | |
fi | |
fi | |
cur_vmaj=${vmaj} | |
cur_vmin=${vmin} | |
cur_tag=${tag} | |
done | |
tags="${tags}${cur_tag}" | |
echo -e "Selected tags:\n${tags}\n" | |
# Set the variables so that they are available for the next steps | |
echo 'BRANCHES<<EOF' >> $GITHUB_ENV | |
echo ${branches} >> $GITHUB_ENV | |
echo 'EOF' >> $GITHUB_ENV | |
echo 'TAGS<<EOF' >> $GITHUB_ENV | |
echo ${tags} >> $GITHUB_ENV | |
echo 'EOF' >> $GITHUB_ENV | |
- name: Install dependencies | |
run: | | |
# Download and install latest doxygen version | |
# wget http://doxygen.nl/files/doxygen-1.9.4.linux.bin.tar.gz -O doxygen.tar.gz | |
wget https://www.doxygen.nl/files/doxygen-1.9.8.linux.bin.tar.gz -O doxygen.tar.gz | |
tar xzf doxygen.tar.gz | |
sudo mv doxygen-*/bin/* /usr/local/bin | |
rm -Rf doxygen.tar.gz doxygen-* | |
# Install doxygen-related tools | |
sudo apt update | |
sudo apt install -qq -y graphviz plantuml texlive-latex-base | |
# Install basics | |
sudo apt-get install -qq -y apt-transport-https ca-certificates gnupg software-properties-common wget | |
sudo apt-get install -qq -y cmake | |
# Install Robotology dependencies (icub-common to be checked) | |
#wget http://www.icub.org/ubuntu/pool/contrib/science/i/icub-common/icub-common_1.25.0-1~jammy_amd64.deb -O icub-common.deb | |
#wget http://www.icub.org/ubuntu/pool/contrib/science/y/ycm-cmake-modules/ycm-cmake-modules_0.14.1~jammy_amd64.deb -O ycm-cmake-modules.deb | |
wget https://github.com/robotology/ycm/releases/download/v0.15.3/ycm-cmake-modules-0.15.3-all.deb -O ycm-cmake-modules.deb | |
#sudo dpkg -i icub-common.deb | |
sudo dpkg -i ycm-cmake-modules.deb | |
#rm -f icub-common.deb | |
rm -f ycm-cmake-modules.deb | |
#maybe useless? | |
#sudo apt install -qq -ylibclang1-9 libclang-cpp9 | |
# Install lots of YARP dependencies (some of them may be duplicated from icub-common) | |
sudo apt-get install -qq -y cmake \ | |
libace-dev \ | |
libsqlite3-dev \ | |
libtinyxml-dev \ | |
libedit-dev \ | |
qtbase5-dev \ | |
qtdeclarative5-dev \ | |
qtmultimedia5-dev \ | |
libqt5opengl5-dev \ | |
libqcustomplot-dev \ | |
libopencv-dev \ | |
libeigen3-dev \ | |
libjpeg-dev \ | |
libpng-dev \ | |
libgraphviz-dev \ | |
libpng-dev \ | |
libv4l-dev \ | |
libavcodec-dev \ | |
libavdevice-dev \ | |
libavformat-dev \ | |
libavutil-dev \ | |
portaudio19-dev | |
# Not working on Ubuntu 22.04 (to be fixed?) | |
# sudo apt-get install -qq -y libgstreamer1.0-dev \ | |
# libgstreamer-plugins-base1.0-dev \ | |
- name: Checkout previously generated documentation | |
run: | | |
# For each tag, if the directory already exists in latest generation, | |
# recover it, and use it without re-generating it. | |
for ref in ${TAGS}; do | |
echo "-------------------------------------------------------------" | |
echo "Checking tag ${ref}:" | |
echo | |
ver=$(echo ${ref} | sed 's/v//') | |
vmaj=$(echo ${ver} | cut -d'.' -f1) | |
vmin=$(echo ${ver} | cut -d'.' -f2) | |
dir=$(echo ${ref} | sed 's/^\(v[0-9]\+\.[0-9]\+\).*$/\1/') | |
git checkout origin/yarp_it_pages -- ${dir} 2>/dev/null || true | |
git reset -q | |
if [ -f ${dir}/index.html ]; then | |
cur_ver=$(grep VERSION ${dir}/index.html | sed "s/[^']\+'\([^']\+\).\+/\1/g") | |
if [ "${cur_ver}" != "${ver}" ]; then | |
# Same directory, but not the same tag. Must be deleted | |
echo Directory ${dir} was found, but tag is different. Found ${cur_ver}, expected "${ver}". Deleting folder. | |
rm -rf ${dir} | |
else | |
echo Reusing documentation for ref ${ref} in dir ${dir} | |
fi | |
else | |
echo | |
echo Documentation for tag ${ref} not found | |
fi | |
done | |
- name: Generate documentation | |
run: | | |
# Generate the documentation for all tags and branches (if the | |
# corresponding directory does not exist) | |
for ref in ${TAGS} ${BRANCHES}; do | |
if [[ ${ref} =~ ^v[0-9]+\.[0-9]+ ]]; then | |
dir=$(echo ${ref} | sed 's/^\(v[0-9]\+\.[0-9]\+\).*$/\1/') | |
else | |
dir="git-${ref}" | |
fi | |
if [ ! -d ${dir} ]; then | |
echo | |
echo "Generating documentation for ref ${ref} in dir ${dir}" | |
echo | |
git -C ${YARP_CHECKOUT_DIR} checkout ${ref} | |
binary_dir=yarp-${dir}-build | |
# Run CMake | |
mkdir -p ${binary_dir} | |
/usr/bin/cmake -Hyarp -B${binary_dir} -G"Unix Makefiles" \ | |
-DYARP_DOXYGEN_HTML:BOOL=ON \ | |
-DYARP_DOXYGEN_XML:BOOL=ON \ | |
-DYARP_DOXYGEN_TAGFILE:BOOL=ON \ | |
-DYARP_USE_SYSTEM_YCM:BOOL=OFF 2>&1 | tee ${binary_dir}/cmake.log | |
# Build the documentation | |
/usr/bin/cmake --build ${binary_dir} --target dox 2>&1 | tee ${binary_dir}/dox.log | |
# Move generated documentation in its final destination | |
mv ${binary_dir}/dox/html ${dir} | |
# Make available logs and doxygen.log, in case someone needs to | |
# fix something or wants to clean some doxygen warnings | |
mv ${binary_dir}/cmake.log ${dir} | |
mv ${binary_dir}/dox.log ${dir} | |
if [ -f ${binary_dir}/doc/doxygen.log ]; then | |
mv ${binary_dir}/doc/doxygen.log ${dir} | |
fi | |
if [ -f ${binary_dir}/doxygen.log ]; then | |
mv ${binary_dir}/doxygen.log ${dir} | |
fi | |
# Make the tag file available | |
mv ${binary_dir}/dox/YARP.tag ${dir} | |
# Hide doxygen banner and generation date | |
if [ -f ${dir}/yarp-doxygen-style.css ]; then | |
echo "" >> ${dir}/yarp-doxygen-style.css | |
echo "/* Hide doxygen banner and generation date */" >> ${dir}/yarp-doxygen-style.css | |
echo ".navpath li.footer {" >> ${dir}/yarp-doxygen-style.css | |
echo " visibility: hidden;" >> ${dir}/yarp-doxygen-style.css | |
echo "}" >> ${dir}/yarp-doxygen-style.css | |
fi | |
fi | |
git add ${dir} | |
git commit -m "Generate documentation for YARP ${ref}" | |
# Push every commit on a temporary branch to avoid | |
# "remote: fatal: pack exceeds maximum allowed size" | |
# errors when we push everything at the end, and be sure to wait for | |
# the whole generation before pushing on the yarp_it_pages branch. | |
git push --force origin HEAD:refs/heads/yarp_it_pages-tmp | |
done | |
# Add symbolic link to the latest release | |
for ref in ${TAGS}; do | |
dir=$(echo ${ref} | sed 's/^\(v[0-9]\+\.[0-9]\+\).*$/\1/') | |
done | |
ln -s ${dir} latest | |
git add latest | |
git commit -m "Add link from ${dir} to latest" | |
git push --force origin HEAD:refs/heads/yarp_it_pages-tmp | |
- name: Generate version_switch.js | |
run: | | |
unset all_tags_versions | |
unset all_versions | |
for ref in ${BRANCHES} ${TAGS}; do | |
if [[ ${ref} =~ ^v[0-9]+\.[0-9]+ ]]; then | |
dir=$(echo ${ref} | sed 's/^\(v[0-9]\+\.[0-9]\+\).*$/\1/') | |
all_tags_versions="${all_tags_versions} '${dir}': '$(echo ${dir} | sed 's/v//')',"$'\n' | |
else | |
dir="git-${ref}" | |
all_versions="${all_versions} '${dir}': '${dir}',"$'\n' | |
fi | |
done | |
all_tags_versions="$(echo "${all_tags_versions}" | sort -Vr)" | |
all_versions="${all_versions} 'latest': 'latest release',"$'\n'"${all_tags_versions}" | |
cat > version_switch.js << EOF | |
(function() { | |
'use strict'; | |
var yarp_url = '${YARP_URL}'; | |
var url_re = /${YARP_URL_RE}(git-master|latest|(v\d\.\d+))\//; | |
var all_versions = { | |
${all_versions} | |
}; | |
function build_select(current_version, current_release) { | |
var buf = ['<select>']; | |
\$.each(all_versions, function(version, title) { | |
buf.push('<option value="' + version + '"'); | |
if (version == current_version) { | |
buf.push(' selected="selected">'); | |
if (version[0] == 'v') { | |
buf.push(current_release); | |
} else { | |
buf.push(title + ' (' + current_release + ')'); | |
} | |
} else { | |
buf.push('>' + title); | |
} | |
buf.push('</option>'); | |
}); | |
buf.push('</select>'); | |
return buf.join(''); | |
} | |
function patch_url(url, new_version) { | |
return url.replace(url_re, yarp_url + new_version + '/'); | |
} | |
function on_switch() { | |
var selected = \$(this).children('option:selected').attr('value'); | |
var url = window.location.href, | |
new_url = patch_url(url, selected); | |
if (new_url != url) { | |
// check beforehand if url exists, else redirect to version's start page | |
\$.ajax({ | |
url: new_url, | |
success: function() { | |
window.location.href = new_url; | |
}, | |
error: function() { | |
window.location.href = window.location.protocol + '//' + yarp_url + selected; | |
} | |
}); | |
} | |
} | |
\$(document).ready(function() { | |
var match = url_re.exec(window.location.href); | |
if (match) { | |
var release = DOCUMENTATION_OPTIONS.VERSION; | |
var version = match[2]; | |
var select = build_select(version, release); | |
\$('.version_switch').html(select); | |
\$('.version_switch select').bind('change', on_switch); | |
} | |
}); | |
})(); | |
EOF | |
git add version_switch.js | |
git commit -m "Add version_switch.js" | |
git push --force origin HEAD:refs/heads/yarp_it_pages-tmp | |
- name: Generate redirect from top directory to latest | |
run: | | |
_yarp_url=$(echo ${YARP_URL} | sed 's/www\./\$1/g') | |
cat > redirect.js << EOF | |
(function() { | |
function patch_url(url) { | |
return url.replace(/${YARP_URL_RE}/, '${_yarp_url}latest/'); | |
} | |
function patch_missing_url(url) { | |
return url.replace(/${YARP_URL_RE}.+/, '${_yarp_url}latest/'); | |
} | |
\$(document).ready(function() { | |
var timeout = 0; // seconds | |
var url = window.location.href; | |
var new_url = patch_url(url); | |
if (new_url != url) { | |
// check beforehand if url exists, else redirect to version's start page | |
\$.ajax({ | |
url: new_url, | |
success: function() { | |
\$('head').append( '<meta http-equiv="refresh" content="' + timeout + '; url=' + new_url + '" />' ); | |
\$('.textblock').html('<p>This page has moved.</p><p>If you are not redirected automatically within a few seconds, follow this link to the new address: <a href="' | |
+ new_url + '">' + new_url + "</a>.</p>"); | |
setTimeout(function () { window.location.href = new_url; }, timeout * 1000); | |
}, | |
error: function() { | |
new_url = patch_missing_url(url); | |
\$('head').append( '<meta http-equiv="refresh" content="' + timeout + '; url=' + new_url + '" />' ); | |
\$('.textblock').html('<p>This page no longer exists.</p><p>If you are not redirected automatically within a few seconds, follow this link to the YARP documentation: <a href="' | |
+ new_url + '">' + new_url + "</a>.</p>"); | |
setTimeout(function () { window.location.href = new_url; }, timeout * 1000); | |
} | |
}); | |
} else { | |
// Either a local copy of the documentation, or on the wrong website. | |
path = window.location.href.substring(0, window.location.href.lastIndexOf("/")); | |
if (path != "") { | |
path = path + "/"; | |
} | |
new_url = path + "latest/" + file; | |
\$('head').append( '<meta http-equiv="refresh" content="' + timeout + '; url=' + new_url + '" />' ); | |
\$('.textblock').html('<p>This page has moved.</p><p>If you are not redirected automatically within a few seconds, follow this link to the new address: <a href="' | |
+ new_url + '">' + new_url + "</a>.</p>"); | |
setTimeout(function () { window.location.href = new_url; }, timeout * 1000); | |
} | |
}); | |
})(); | |
EOF | |
cat > index.html << EOF | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | |
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | |
<meta name="viewport" content="width=device-width, initial-scale=1"/> | |
<title>YARP: Page Redirection</title> | |
<link rel="shortcut icon" href="latest/yarp-favicon.ico" type="image/x-icon" /> | |
<link href="latest/tabs.css" rel="stylesheet" type="text/css"/> | |
<link href="latest/navtree.css" rel="stylesheet" type="text/css"/> | |
<link href="latest/doxygen.css" rel="stylesheet" type="text/css" /> | |
<link href="latest/yarp-doxygen-style.css" rel="stylesheet" type="text/css"/> | |
<script type="text/javascript" src="latest/jquery.js"></script> | |
<script type="text/javascript" src="latest/dynsections.js"></script> | |
<script type="text/javascript" src="latest/resize.js"></script> | |
<script type="text/javascript" src="latest/navtreedata.js"></script> | |
<script type="text/javascript" src="latest/navtree.js"></script> | |
<script type="text/javascript"> | |
\$(document).ready(initResizable); | |
</script> | |
<script type="text/javascript" src="version_switch.js"></script> | |
<script type="text/javascript"> | |
\$(document).ready(function() { | |
\$('#version-selector').load('some-local-path/menu.html'); | |
}); | |
</script> | |
<script type="text/javascript" src="redirect.js"></script> | |
</script> | |
</head> | |
<body> | |
<div id="top"> | |
<div id="titlearea"> | |
<table cellspacing="0" cellpadding="0"> | |
<tbody> | |
<tr style="height: 56px;"> | |
<td id="projectlogo"><img alt="Logo" src="latest/yarp-robot-64.png"/></td> | |
<td id="projectalign" style="padding-left: 1.5em;"> | |
<div id="projectname">YARP</div> | |
<div id="projectbrief">Yet Another Robot Platform</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<div id="side-nav" class="ui-resizable side-nav-resizable"> | |
<div id="nav-tree"> | |
<div id="nav-tree-contents"> | |
<div id="nav-sync" class="sync"> </div> | |
</div> | |
</div> | |
<div id="splitbar" style="-moz-user-select:none;" class="ui-resizable-handle"> </div> | |
</div> | |
<div id="doc-content"> | |
<div class="header"> | |
<div class="headertitle"> | |
<div class="title">Page Moved</div> | |
</div> | |
</div> | |
<div class="contents"> | |
<div class="textblock"> | |
</div> | |
</div> | |
</div> | |
<div id="nav-path" class="navpath"> | |
<ul> | |
<li><span id="projectname_footer">YARP</span></li> | |
<li><span id="projectnumber" class="version_switch"> | |
<select> | |
<option value="latest" selected="selected">latest | |
           | |
           | |
           | |
        </option> | |
</select></span></li> | |
<li class="footer"></li> | |
</ul> | |
</div> | |
</body> | |
</html> | |
EOF | |
for file in $(find latest/ -mindepth 1 -maxdepth 1 -name "*.html" | grep -v index.html); do | |
ln -sfn index.html $(echo $file | sed 's|latest/||') | |
done | |
ln -sfn latest/yarp-favicon.ico favicon.ico | |
git add redirect.js *.html favicon.ico | |
git commit -m "Add redirect from top directory to latest" | |
git push --force origin HEAD:refs/heads/yarp_it_pages-tmp | |
- name: Generate CNAME file | |
run: | | |
echo -n ${YARP_CNAME} > CNAME | |
git add CNAME | |
git commit -m "Add CNAME file" | |
git push --force origin HEAD:refs/heads/yarp_it_pages-tmp | |
- name: Commit and push the yarp_it_pages branch | |
run: | | |
commit_yarp=$(git -C ${YARP_CHECKOUT_DIR} rev-parse origin/master) | |
git commit -m "Generate documentation" --allow-empty -m "yarp: ${commit_yarp}" -m "yarp-documentation: ${GITHUB_SHA}" | |
git push --force origin yarp_it_pages | |
# Delete the temporary branch | |
git push origin :yarp_it_pages-tmp |