ci: replace Travis with GitHub Actions

Minor cleanups in docs and build scripts

Change-Id: Icfab337d1b9c78f91ea0c47b65eb4dae6d589b18
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..e988485
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,68 @@
+name: CI
+on:
+  push:
+    paths-ignore:
+      - 'docs/**'
+      - '*.md'
+      - '.mailmap'
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  linux:
+    name: ${{ matrix.compiler }} on ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        compiler: [g++-8, g++-9, g++-10, g++-11,
+                   clang++-7, clang++-8, clang++-9, clang++-10, clang++-11, clang++-12]
+        os: [ubuntu-20.04]
+        include:
+          - compiler: g++-7
+            os: ubuntu-18.04
+          - compiler: clang++-5.0
+            os: ubuntu-18.04
+          - compiler: clang++-6.0
+            os: ubuntu-18.04
+    runs-on: ${{ matrix.os }}
+    env:
+      CXX: ${{ matrix.compiler }}
+      NODE_LABELS: Linux Ubuntu
+      WAF_JOBS: 2
+    steps:
+      - name: Install C++ compiler
+        run: |
+          sudo apt-get -qy install ${CXX/clang++/clang}
+          ${CXX} --version
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Build and test
+        run: ./.jenkins
+
+  macos:
+    name: Xcode ${{ matrix.xcode }} on ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        xcode: ['11.3', '11.7', '12.4']
+        os: [macos-10.15]
+        include:
+          - xcode: '12.5'
+            os: macos-11
+          - xcode: '13'
+            os: macos-11
+    runs-on: ${{ matrix.os }}
+    env:
+      NODE_LABELS: OSX
+      WAF_JOBS: 3
+    steps:
+      - name: Set up Xcode
+        uses: maxim-lobanov/setup-xcode@v1
+        with:
+          xcode-version: ${{ matrix.xcode }}
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Build and test
+        run: ./.jenkins
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 0000000..c24966a
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,37 @@
+name: Docs
+on:
+  push:
+    paths-ignore:
+      - '*.md'
+      - '.mailmap'
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  build:
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [macos-11, ubuntu-20.04]
+    runs-on: ${{ matrix.os }}
+    env:
+      JOB_NAME: Docs
+      WAF_JOBS: 3
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install dependencies
+        run: |
+          case ${RUNNER_OS} in
+            Linux) export NODE_LABELS="Linux Ubuntu" ;;
+            macOS) export NODE_LABELS="OSX" ;;
+          esac
+          find .jenkins.d/ -type f -name '[1-9]*.sh' -exec chmod -x '{}' +
+          ./.jenkins
+      - name: Build documentation
+        run: |
+          ./waf --color=yes configure
+          ./waf --color=yes build --targets=version.hpp
+          ./waf --color=yes docs
diff --git a/.jenkins b/.jenkins
index bc1c847..da10d69 100755
--- a/.jenkins
+++ b/.jenkins
@@ -2,31 +2,25 @@
 set -e
 source .jenkins.d/util.sh
 
+if has Linux $NODE_LABELS; then
+    export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
+fi
 export CACHE_DIR=${CACHE_DIR:-/tmp}
 export WAF_JOBS=${WAF_JOBS:-1}
 [[ $JOB_NAME == *"code-coverage" ]] && export DISABLE_ASAN=yes
 
-nanos() {
-    # Cannot use date(1) because macOS does not support %N format specifier
-    python3 -c 'import time; print(int(time.time() * 1e9))'
-}
-
 for file in .jenkins.d/*; do
     [[ -f $file && -x $file ]] || continue
 
-    if [[ -n $TRAVIS ]]; then
+    if [[ -n $GITHUB_ACTIONS ]]; then
         label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
-        echo -ne "travis_fold:start:${label}\r"
-        echo -ne "travis_time:start:${label}\r"
-        start=$(nanos)
+        echo "::group::${label}"
     fi
 
     echo "\$ $file"
     "$file"
 
-    if [[ -n $TRAVIS ]]; then
-        finish=$(nanos)
-        echo -ne "travis_time:end:${label}:start=${start},finish=${finish},duration=$((finish-start)),event=${label}\r"
-        echo -ne "travis_fold:end:${label}\r"
+    if [[ -n $GITHUB_ACTIONS ]]; then
+        echo "::endgroup::"
     fi
 done
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
index cd3eb76..95dfe37 100755
--- a/.jenkins.d/00-deps.sh
+++ b/.jenkins.d/00-deps.sh
@@ -3,13 +3,13 @@
 
 if has OSX $NODE_LABELS; then
     FORMULAE=(boost openssl pkg-config)
-    if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
-        FORMULAE+=(python)
+    if [[ $JOB_NAME == *"Docs" ]]; then
+        FORMULAE+=(doxygen graphviz)
     fi
 
-    if [[ -n $TRAVIS ]]; then
-        # Travis images come with a large number of pre-installed
-        # brew packages, don't waste time upgrading all of them
+    if [[ -n $GITHUB_ACTIONS ]]; then
+        # GitHub Actions runners have a large number of pre-installed
+        # Homebrew packages. Don't waste time upgrading all of them.
         brew list --versions "${FORMULAE[@]}" || brew update
         for FORMULA in "${FORMULAE[@]}"; do
             brew list --versions "$FORMULA" || brew install "$FORMULA"
@@ -23,12 +23,23 @@
         brew cleanup
     fi
 
+    if [[ $JOB_NAME == *"Docs" ]]; then
+        pip3 install --upgrade --upgrade-strategy=eager sphinx sphinxcontrib-doxylink
+    fi
+
 elif has Ubuntu $NODE_LABELS; then
     sudo apt-get -qq update
     sudo apt-get -qy install build-essential pkg-config python3-minimal \
                              libboost-all-dev libssl-dev libsqlite3-dev
 
-    if [[ $JOB_NAME == *"code-coverage" ]]; then
-        sudo apt-get -qy install gcovr lcov
-    fi
+    case $JOB_NAME in
+        *code-coverage)
+            sudo apt-get -qy install lcov python3-pip
+            pip3 install --user --upgrade --upgrade-strategy=eager 'gcovr~=5.0'
+            ;;
+        *Docs)
+            sudo apt-get -qy install doxygen graphviz python3-pip
+            pip3 install --user --upgrade --upgrade-strategy=eager sphinx sphinxcontrib-doxylink
+            ;;
+    esac
 fi
diff --git a/.jenkins.d/09-cleanup.sh b/.jenkins.d/09-cleanup.sh
new file mode 100755
index 0000000..e1c0a2e
--- /dev/null
+++ b/.jenkins.d/09-cleanup.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -ex
+
+PROJ=ndn-nac
+
+sudo rm -fr /usr/local/include/"$PROJ"
+sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
+sudo rm -f /usr/local/lib{,64}/pkgconfig/{,lib}"$PROJ".pc
diff --git a/.jenkins.d/30-coverage.sh b/.jenkins.d/30-coverage.sh
index c77175f..70c5c9b 100755
--- a/.jenkins.d/30-coverage.sh
+++ b/.jenkins.d/30-coverage.sh
@@ -2,29 +2,26 @@
 set -ex
 
 if [[ $JOB_NAME == *"code-coverage" ]]; then
+    # Generate an XML report (Cobertura format)
     gcovr --object-directory=build \
           --output=build/coverage.xml \
           --exclude="$PWD/tests" \
           --root=. \
           --xml
 
-    # Generate also a detailed HTML output, but using lcov (better results)
+    # Generate a detailed HTML report using lcov
     lcov --quiet \
          --capture \
          --directory . \
+         --exclude "$PWD/tests/*" \
          --no-external \
          --rc lcov_branch_coverage=1 \
-         --output-file build/coverage-with-tests.info
-
-    lcov --quiet \
-         --remove build/coverage-with-tests.info "$PWD/tests/*" \
-         --rc lcov_branch_coverage=1 \
          --output-file build/coverage.info
 
     genhtml --branch-coverage \
             --demangle-cpp \
             --legend \
-            --output-directory build/coverage \
+            --output-directory build/lcov \
             --title "ndn-nac unit tests" \
             build/coverage.info
 fi
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 8ff6d27..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,105 +0,0 @@
-version: ~> 1.0
-language: cpp
-os: linux
-dist: bionic
-
-arch:
-  - amd64
-  - arm64
-  - ppc64le
-  - s390x
-
-env:
-  - COMPILER=g++-7
-  - COMPILER=g++-9
-  - COMPILER=clang++-6.0
-  - COMPILER=clang++-9
-
-jobs:
-  include:
-    # Linux
-    - env: COMPILER=g++-8
-    - env: COMPILER=clang++-5.0
-    - env: COMPILER=clang++-7
-    - env: COMPILER=clang++-8
-    - env: COMPILER=clang++-10
-    - env: COMPILER=clang++-11
-    - env: COMPILER=clang++-12
-
-    # macOS
-    - os: osx
-      osx_image: xcode9.4
-      env: # default compiler
-    - os: osx
-      osx_image: xcode10.1
-      env: # default compiler
-    - os: osx
-      osx_image: xcode10.3
-      env: # default compiler
-    - os: osx
-      osx_image: xcode11.3
-      env: # default compiler
-    - os: osx
-      osx_image: xcode11.6
-      env: # default compiler
-    - os: osx
-      osx_image: xcode12
-      env: # default compiler
-
-  allow_failures:
-    - env: COMPILER=clang++-12
-
-  fast_finish: true
-
-before_install:
-  - |
-    : Adding apt repositories
-    case ${COMPILER} in
-      g++-9)
-        # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
-        travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
-        travis_retry sudo apt-get -qq update
-        ;;
-      clang++-1?)
-        # https://apt.llvm.org/
-        LLVM_REPO=${COMPILER/clang++/llvm-toolchain-${TRAVIS_DIST}}
-        travis_retry wget -nv -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
-        travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/${TRAVIS_DIST}/ ${LLVM_REPO%-12} main"
-        travis_retry sudo apt-get -qq update
-        ;;
-    esac
-
-install:
-  - |
-    : Installing C++ compiler
-    if [[ -n ${COMPILER} ]]; then
-      travis_retry sudo apt-get -qy install ${COMPILER/clang++/clang}
-    fi
-
-before_script:
-  - |
-    : Setting environment variables
-    if [[ -n ${COMPILER} ]]; then
-      export CXX=${COMPILER}
-    fi
-    case ${TRAVIS_OS_NAME} in
-      linux)  export NODE_LABELS="Linux Ubuntu Ubuntu-18.04" ;;
-      osx)    export NODE_LABELS="OSX OSX-$(sw_vers -productVersion | cut -d . -f -2)" ;;
-    esac
-    export WAF_JOBS=2
-  - |
-    : Enabling workarounds
-    case "${TRAVIS_CPU_ARCH},${COMPILER}" in
-      ppc64le,g++-7)
-        # AddressSanitizer does not seem to be working
-        export DISABLE_ASAN=yes
-        ;;
-      *,clang++-8)
-        # https://bugs.llvm.org/show_bug.cgi?id=40808
-        export DISABLE_ASAN=yes
-        ;;
-    esac
-  - ${CXX:-c++} --version
-
-script:
-  - ./.jenkins
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index 9e045c3..70b6624 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -184,7 +184,8 @@
             flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
                                   ['-isystem', '/opt/local/include']] # for MacPorts
         if Utils.unversioned_sys_platform() == 'freebsd':
-            flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']] # Bug #4790
+            # Bug #4790
+            flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
         return flags
 
     def getDebugFlags(self, conf):
@@ -194,10 +195,7 @@
                               '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        version = self.getCompilerVersion(conf)
-        if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
-            flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
-        if version < (6, 0, 0):
+        if self.getCompilerVersion(conf) < (6, 0, 0):
             flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
 
@@ -208,9 +206,6 @@
                               '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        version = self.getCompilerVersion(conf)
-        if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
-            flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
-        if version < (6, 0, 0):
+        if self.getCompilerVersion(conf) < (6, 0, 0):
             flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
diff --git a/README.md b/README.md
index 07e2330..13b6f81 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
 # NAC: Named-Based Access Control Library for NDN
 
-![Language](https://img.shields.io/badge/C%2B%2B-14-blue.svg)
-[![Build Status](https://travis-ci.org/named-data/name-based-access-control.svg?branch=new)](https://travis-ci.org/named-data/name-based-access-control)
+[![CI](https://github.com/named-data/name-based-access-control/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/name-based-access-control/actions/workflows/ci.yml)
+[![Docs](https://github.com/named-data/name-based-access-control/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/name-based-access-control/actions/workflows/docs.yml)
+![Language](https://img.shields.io/badge/C%2B%2B-14-blue)
 
 ## Reporting bugs
 
diff --git a/docs/conf.py b/docs/conf.py
index 1cf79b2..e88e6bf 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,10 +1,8 @@
-# -*- coding: utf-8 -*-
-#
 # Configuration file for the Sphinx documentation builder.
 #
 # This file only contains a selection of the most common options. For a full
 # list see the documentation:
-# http://www.sphinx-doc.org/en/master/config
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
 
 # -- Path setup --------------------------------------------------------------
 
@@ -20,13 +18,13 @@
 # -- Project information -----------------------------------------------------
 
 project = u'NAC: Name-based Access Control library'
-copyright = u'Copyright © 2014-2020 Regents of the University of California.'
+copyright = u'Copyright © 2014-2021 Regents of the University of California.'
 author = u'Named Data Networking Project'
 
-# The short X.Y version
+# The short X.Y version.
 #version = ''
 
-# The full version, including alpha/beta/rc tags
+# The full version, including alpha/beta/rc tags.
 #release = ''
 
 # There are two options for replacing |today|: either, you set today to some
@@ -40,7 +38,7 @@
 
 # If your documentation needs a minimal Sphinx version, state it here.
 #
-needs_sphinx = '1.1'
+needs_sphinx = '1.3'
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -87,6 +85,12 @@
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ['_static']
 
+html_copy_source = False
+html_show_sourcelink = False
+
+# Disable syntax highlighting of code blocks by default.
+highlight_language = 'none'
+
 
 # -- Options for LaTeX output ------------------------------------------------
 
diff --git a/docs/doxygen.conf.in b/docs/doxygen.conf.in
index 155eeb5..11b3e2e 100644
--- a/docs/doxygen.conf.in
+++ b/docs/doxygen.conf.in
@@ -1640,16 +1640,6 @@
 
 LATEX_HIDE_INDICES     = NO
 
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE      = NO
-
 # The LATEX_BIB_STYLE tag can be used to specify the style to use for the
 # bibliography, e.g. plainnat, or ieeetr. See
 # http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
diff --git a/docs/index.rst b/docs/index.rst
index ecf8f81..0cd704e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,14 +1,14 @@
 NAC: Name-Based Access Control
 ==============================
 
-NAC is a C++ library, implementing Name-Based Access control primitives that can be
-used to implement content confidentiality in NDN applications.
+NAC is a C++ library providing Name-Based Access control primitives that
+can be used to implement content confidentiality in NDN applications.
 
-Please submit any bugs or issues to the `NAC issue tracker
-<http://redmine.named-data.net/projects/nac/issues>`__.
+Please submit any bug reports or feature requests to the `NAC issue tracker
+<https://redmine.named-data.net/projects/nac/issues>`__.
 
-NAC Documentation
----------------------
+Documentation
+-------------
 
 .. toctree::
    :hidden:
@@ -17,13 +17,10 @@
    spec
 
 - :doc:`spec`
-
-**Additional documentation**
-
 - `API documentation (doxygen) <doxygen/annotated.html>`_
 
 License
 -------
 
-NAC is an open source project licensed under LGPL 3.0 license. For more information about
+NAC is an open source project licensed under the LGPL version 3. For more information about
 the license, refer to `COPYING.md <https://github.com/named-data/name-based-access-control/blob/master/COPYING.md>`_.
diff --git a/docs/spec.rst b/docs/spec.rst
index 659cde5..bb706f3 100644
--- a/docs/spec.rst
+++ b/docs/spec.rst
@@ -59,7 +59,7 @@
 .. code-block:: abnf
 
    Kek = DATA-TYPE TLV-LENGTH
-         Name ; /[access-namespace]/NAC/[dataset]/KEK/[key-id]
+         Name     ; /[access-namespace]/NAC/[dataset]/KEK/[key-id]
          MetaInfo ; ContentType = KEY, FreshnessPeriod = 1 hour default value
          KekContent
          DataSignature
@@ -73,7 +73,7 @@
 .. code-block:: abnf
 
    Kdk = DATA-TYPE TLV-LENGTH
-         Name ; /[access-namespace]/NAC/[dataset]/KDK/[key-id]/ENCRYPTED-BY/<authorized-member>/KEY/[member-key-id]
+         Name     ; /[access-namespace]/NAC/[dataset]/KDK/[key-id]/ENCRYPTED-BY/<authorized-member>/KEY/[member-key-id]
          MetaInfo ; ContentType = BLOB, FreshnessPeriod = 1 hour default value
          KdkContent
          DataSignature
@@ -83,7 +83,7 @@
 
 Within the ``EncryptedContent`` element,
 
-* ``EncryptedPayload`` contains `SafeBag <https://named-data.net/doc/ndn-cxx/0.7.0/specs/safe-bag.html>`__ of private key ``/[access-namespace]/NAC/[dataset]/KEY/[key-id]``
+* ``EncryptedPayload`` contains `SafeBag <https://named-data.net/doc/ndn-cxx/0.7.1/specs/safe-bag.html>`__ of private key ``/[access-namespace]/NAC/[dataset]/KEY/[key-id]``
 * ``EncryptedPayloadKey`` contains password for SafeBag, encrypted by public key ``/<authorized-member>/KEY/[member-key-id]``
 * ``InitializationVector`` and ``Name`` must be omitted
 
@@ -100,7 +100,7 @@
 
      EncryptedPayload      = AES CBC encrypted blob
      InitializationVector  = Random initial vector for AES CBC encryption
-     EncryptedPayloadKey (not set)
+     EncryptedPayloadKey   (not set)
      Name                  = Prefix of ContentKey (CK) data packet /[ck-prefix]/CK/[ck-id]
 
 During initialization or when requested by the application, the Encryptor (re-)generates a random key for AES CBC encryption.
@@ -109,7 +109,7 @@
 .. code-block:: abnf
 
    CkData = DATA-TYPE TLV-LENGTH
-            Name ; /[ck-prefix]/CK/[ck-id]/ENCRYPTED-BY/[access-namespace]/NAC/[dataset]/KEK/[key-id]
+            Name     ; /[ck-prefix]/CK/[ck-id]/ENCRYPTED-BY/[access-namespace]/NAC/[dataset]/KEK/[key-id]
             MetaInfo ; ContentType = BLOB, FreshnessPeriod = 1 hour default value
             CkContent
             DataSignature
diff --git a/src/access-manager.hpp b/src/access-manager.hpp
index 3491955..22dc2cc 100644
--- a/src/access-manager.hpp
+++ b/src/access-manager.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019, Regents of the University of California
+ * Copyright (c) 2014-2021, Regents of the University of California
  *
  * NAC library is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free Software
@@ -47,8 +47,6 @@
 
 public:
   /**
-   * @param identity Identity of the namespace (i.e., public and private keys)
-   *
    * @param identity Data owner's namespace identity (will be used to sign KEK and KDK)
    * @param dataset Name of dataset that this manager is controlling
    * @param keyChain KeyChain