devcontainers: add initial dev-container setup and scripts #671
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
--- | |
# | |
# .github/workflows/cpp.yml | |
# | |
name: C++ Workflow 3.0 | |
on: # yamllint disable-line rule:truthy | |
pull_request: | |
workflow_dispatch: | |
defaults: | |
run: | |
shell: bash | |
jobs: | |
stage1: | |
name: Change Check | |
runs-on: 'ubuntu-latest' | |
outputs: | |
docs_changed: ${{ steps.check_file_changed.outputs.docs_changed }} | |
matrix_exercise: ${{ steps.check_file_changed.outputs.matrix_exercise }} | |
exercise_count: ${{ steps.check_file_changed.outputs.exercise_count }} | |
steps: | |
- name: Check GitHub Vars | |
id: github-vars | |
run: set | grep -e ^CI -e ^GITHUB_ -e ^RUNNER_ | |
- name: Checkout Repo | |
id: checkout-repo | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
ref: ${{ github.ref }} | |
submodules: recursive | |
- name: Get Change List | |
id: check_file_changed | |
run: | | |
{ | |
printf "Workflow: %s\n\n" "${GITHUB_WORKFLOW}" | |
printf "Runner: name[%s] arch[%s]\n" "${RUNNER_NAME}" "${RUNNER_ARCH}" | |
printf "Repo: %s\n" "${GITHUB_REPOSITORY}" | |
printf "User: %s\n" "${GITHUB_TRIGGERING_ACTOR}" | |
printf "\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
# Diff HEAD with the previous commit then output to stdout. | |
GIT_DIFF="$(git diff --name-only HEAD^ HEAD | tee /tmp/changed_files.txt)" | |
{ | |
printf "=== Which files changed? ===\n" | |
printf "\`\`\`text\n" | |
printf "%s\n" "${GIT_DIFF}" | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
HAS_WF_DIFF=false | |
HAS_EX_DIFF=false | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(.github/workflows/cpp.yml|.github/citools/cpp/)$'; then | |
HAS_WF_DIFF=true | |
fi | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(cpp/.*[.](cpp|h|hpp)|cpp/.*/[Ma]akefile|cpp/.*/CMakeLists.txt)$'; then | |
HAS_EX_DIFF=true | |
fi | |
printf "\n" | |
printf "=== Did WF/CI change without exercise changes? ===\n" | |
CI_FORCE_FULL=false | |
if ${HAS_WF_DIFF} && ! ${HAS_EX_DIFF}; then | |
CI_FORCE_FULL=true | |
printf "%s\n" "${CI_FORCE_FULL}" | |
fi | |
printf "\n" | |
# Get changed exercise list. | |
if [[ ${GITHUB_EVENT_NAME} == pull_request ]] && ! ${CI_FORCE_FULL}; then | |
printf "Generating pull request changed exercise list.\n" | |
grep -E '^cpp/[-a-z0-9]+./.*$' /tmp/changed_files.txt | cut -f1,2 -d/ | sort -Vu | tee /tmp/exercises.txt || true | |
else | |
printf "Generating complete exercise list.\n" | |
find ./cpp/ -type d -print | grep -v -E '^[.]/cpp/(|[.].*)$' | sed -r -e 's:[.]/(cpp/[-a-z0-9]+)/?.*$:\1:g' | sort -Vu | tee /tmp/exercises.txt || true | |
HAS_DIFF=true | |
fi | |
printf "\n" | |
# Check if the files are present in the changed file list (added, modified, deleted) then output to stdout. | |
HAS_DIFF="${HAS_DIFF:-false}" | |
printf "=== Which C++ files changed? ===\n" | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(cpp/.*[.](cpp|h|hpp)|cpp/.*/[Ma]akefile|cpp/.*/CMakeLists.txt|.github/workflows/cpp.yml|.github/citools/cpp/.*)$'; then | |
HAS_DIFF=true | |
printf "%s\n" "${HAS_DIFF}" | |
fi | |
printf "\n" | |
# Did C++ files change? | |
printf "=== Did C++ files change? ===\n" | |
printf "%s\n" "${HAS_DIFF}" | |
printf "\n" | |
# Generate exercise job matrix from changed files list. | |
printf "=== Generating matrix exercise list. ===\n" | |
declare -i last=0 | |
declare -i count=0 | |
last=$(wc -l /tmp/exercises.txt | cut -f1 -d\ ) | |
((last -= 1)) || true | |
entries="" | |
while read -r line; do | |
if [[ ! ${count} -lt ${last} ]]; then | |
comma="" | |
else | |
comma="," | |
fi | |
printf -v entry "\"%s\"%s\n" "${line}" "${comma}" | |
((count += 1)) | |
entries+="${entry}" | |
done < <(sort -V /tmp/exercises.txt) | |
jq --sort-keys . >/tmp/exercises.json <<EOF | |
[ ${entries} ] | |
EOF | |
exercise_count="$(jq '. | length' /tmp/exercises.json)" | |
printf "%s=%s\n" "exercise_count" "${exercise_count}" | tee -a "${GITHUB_OUTPUT}" | |
matrix_exercise="$(jq --compact-output --sort-keys . /tmp/exercises.json)" | |
printf "%s=%s\n" "matrix_exercise" "${matrix_exercise}" | tee -a "${GITHUB_OUTPUT}" | |
printf "\n" | |
cat "${GITHUB_OUTPUT}" | |
# Don't run stage 2 if PR mode doesn't have testable changes. | |
if [[ ${GITHUB_EVENT_NAME} == pull_request ]] && [[ -z ${entries} ]]; then | |
printf "In PR mode with no testable changes, disabling stage 2.\n" | |
HAS_DIFF=false | |
fi | |
# Set the output named "docs_changed" | |
printf "%s=%s\n" "docs_changed" "${HAS_DIFF}" >> "${GITHUB_OUTPUT}" | |
check-matrix: | |
runs-on: ubuntu-latest | |
needs: stage1 | |
steps: | |
- name: Install json2yaml | |
run: sudo npm install -g json2yaml | |
- name: Check matrix::exercises | |
run: | | |
exercise_count='${{ needs.stage1.outputs.exercise_count }}' | |
matrix_exercise='${{ needs.stage1.outputs.matrix_exercise }}' | |
{ | |
printf "\`\`\`text\n" | |
printf "exercise_count=%s\n" "${exercise_count}" | |
printf "matrix_exercise=%s\n" "${matrix_exercise}" | |
printf "\`\`\`\n" | |
printf "json:\n" | |
printf "\`\`\`text\n" | |
printf "%s" "${matrix_exercise}" | jq . | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
{ | |
printf "yaml:\n" | |
printf "\`\`\`text\n" | |
printf "{ \"matrix\": { \"exercise\": %s } }" "${matrix_exercise}" | json2yaml | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
stage2: | |
name: C++ Checks | |
strategy: | |
matrix: | |
os: ["ubuntu-latest", "windows-latest", "macos-latest"] | |
exclude: | |
- os: "macos-latest" | |
- os: "windows-latest" | |
exercise: ${{fromJson(needs.stage1.outputs.matrix_exercise)}} | |
runs-on: "${{ matrix.os }}" | |
container: | |
image: vpayno/ci-generic-debian:latest | |
needs: [stage1] | |
if: needs.stage1.outputs.docs_changed == 'True' | |
steps: | |
- name: Checkout Repo [${{ matrix.exercise }}] | |
id: checkout-repo | |
uses: actions/checkout@v3 | |
- name: Install C++ Tools [${{ matrix.exercise }}] | |
id: install-c-tools | |
run: | | |
source .github/citools/includes/wrapper-library | |
if ! grep -q llvm.org /etc/apt/sources.list; then | |
sudo tee -a /etc/apt/sources.list <<EOF | |
# deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy main | |
# deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy main | |
# deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main | |
# deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main | |
# deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main | |
# deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main | |
deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VER} main | |
deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VER} main | |
EOF | |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - | |
fi | |
sudo apt update | |
# sudo apt install -y clang-16 lldb-16 lld-16 | |
# sudo apt install -y libllvm-14-ocaml-dev libllvm14 llvm-14 llvm-14-dev llvm-14-doc llvm-14-examples llvm-14-runtime | |
sudo apt install -y g++ clang-"${LLVM_VER}" clang-tools-"${LLVM_VER}" clang-tidy-"${LLVM_VER}" cmake gcovr | |
sudo apt install -y g++ gcovr | |
sudo apt install -y g++ cmake | |
# sudo apt install -y libssl-dev | |
# sudo apt install -y lcov | |
sudo apt install -y make | |
sudo apt install -y libboost-all-dev | |
- name: CD to C++ Dir [${{ matrix.exercise }}] | |
id: cd-to-c-dir | |
run: | | |
pwd | |
ls | |
cd "./${{ matrix.exercise }}" | |
pwd | |
ls | |
ls | |
- name: Analysing the code with clang-check [${{ matrix.exercise }}] | |
id: clang-check | |
run: | | |
pwd | |
cd "./${{ matrix.exercise }}" | |
pwd | |
ls | |
{ | |
printf "clang-check output\n\n" | |
printf "\`\`\`text\n" | |
../../.github/citools/cpp/clang-check | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
- name: Analysing the code clang-tidy [${{ matrix.exercise }}] | |
id: clang-tidy | |
run: | | |
pwd | |
cd "./${{ matrix.exercise }}" | |
pwd | |
ls | |
{ | |
printf "clang-tidy output\n\n" | |
printf "\`\`\`text\n" | |
../../.github/citools/cpp/clang-tidy | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
- name: Run Unit Tests with Coverage [${{ matrix.exercise }}] | |
id: make-test | |
run: |- | |
pwd | |
cd "./${{ matrix.exercise }}" | |
pwd | |
ls | |
export LDFLAGS="-lgcov --coverage" CXXFLAGS="--coverage" | |
{ | |
printf "Test & Coverage Summary\n\n" | |
printf "\`\`\`text\n" | |
make coverage | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" |