Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 259 additions & 0 deletions .github/workflows/01-make-dist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# Adapted from NUT 01-make-dist.yml with inspiration taken from
# https://javahelps.com/manage-github-artifact-storage-quota
# regarding uploads of artifacts and clearing the way for them.
# See also:
# https://github.com/actions/upload-artifact
# https://docs.github.com/en/actions/reference/workflows-and-actions/variables
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
#name: "GHA-01: Make dist and docs tarballs, see workflow page for links"
name: "GHA-01: Tarballs"

on:
push:
branches: [ "master" ]
tags:
- v*
pull_request_target:
# The branches below must be a subset of the branches above
# Note that for PRs this runs the copy of workflow in the
# target branch (and only then gets some of the permissions
# listed below), and identification/naming of PR source vs.
# a pushed branch (e.g. master updated by a PR merge) is
# tricky.
branches: [ "master" ]
schedule:
- cron: '45 12 * * 0'
workflow_dispatch:
# Allow manually running the action, e.g. if disabled after some quietness in the source

permissions:
checks: write
contents: write
issues: write
pull-requests: write

jobs:
make-dist-tarballs:
name: "Make Dist and Docs Tarballs, see workflow page for links"
# FIXME: Prepare/maintain a container image with pre-installed
# WMNut build/tooling prereqs (save about 3 minutes per run!)
# Maybe https://aschmelyun.com/blog/using-docker-run-inside-of-github-actions/
# => https://github.com/addnab/docker-run-action can help
runs-on: ubuntu-latest

strategy:
fail-fast: false

steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
fetch-tags: true
# NOTE: pull_request_target protects us by using the workflow definition
# from target branch (so trusted operations like artifact management can
# be used), but it also uses the code from that branch too, so fix it back.
# Maybe use "github.event.pull_request.merge_commit_sha" instead?.. though
# it may be null if the PR is not mergeable or is still checked for that,
# or may return the commit for PREVIOUS pushed iteration's merge to target.
# See more ideas in https://github.com/actions/checkout/issues/518 :
ref: "${{ github.event.pull_request.number > 0 && github.event.pull_request.head.sha || github.ref_name }}"
persist-credentials: false

# https://github.com/marketplace/actions/substitute-string
# See also examples in https://github.com/dhimmel/dump-actions-context/
# Note it warns about "unexpected input(s)" with replacement tokens below,
# as they are by design not predefined, as far as actions API is concened.
# They still work for substitutions though.
- uses: bluwy/substitute-string-action@v3
id: subst-github-ref-name
with:
_input-text: "${{ github.event.pull_request.number > 0 && format('PR-{0}', github.event.pull_request.number) || github.head_ref || github.ref_name }}"
" ": _
"/": _

- name: Debug PR/branch identification
run: |
echo "steps.subst-github-ref-name.outputs.result='${{ steps.subst-github-ref-name.outputs.result }}'" || true
echo "github.event.pull_request.number='${{ github.event.pull_request.number }}'" || true
echo "format('PR-{0}', github.event.pull_request.number)='${{ format('PR-{0}', github.event.pull_request.number) }}'" || true
echo "github.head_ref='${{ github.head_ref }}'" || true
echo "github.ref='${{ github.ref }}'" || true
echo "github.ref_name='${{ github.ref_name }}'" || true

# Make build identification more useful (so we use no fallbacks in script)
- name: Try to get more Git metadata
run: |
git describe || {
git remote -v || true
git branch -a || true
for R in `git remote` ; do git fetch $R master ; done || true
git fetch --tags
pwd ; ls -la
echo "=== Known commits in history:"
git log --oneline | wc -l
echo "=== Recent commits in history:"
git log -2 || true
echo "=== Known tags:"
git tag || true
echo "=== Try to ensure 'git describe' works:"
git describe || {
git fetch --all && for R in `git remote` ; do for T in `git tag` ; do git fetch $R $T ; done ; done
git describe || {
TEST_REF="`git symbolic-ref --short HEAD 2>/dev/null || cat .git/HEAD`" && [ -n "${TEST_REF}" ] && git checkout master && git pull --all && git checkout "${TEST_REF}"
git describe || true
}
}
}

# Using hints from https://askubuntu.com/questions/272248/processing-triggers-for-man-db
# and our own docs/config-prereqs.txt
# NOTE: Currently installing the MAX prerequisite footprint,
# which for building just the docs may be a bit of an overkill.
- name: WMNut CI Prerequisite packages (Ubuntu, GCC)
run: |
echo "set man-db/auto-update false" | sudo debconf-communicate
sudo dpkg-reconfigure man-db
sudo apt update
sudo apt install \
gcc g++ clang \
libxpm-dev libxext-dev libupsclient-dev libc6-dev-amd64-cross libgcc-s1-amd64-cross ccache \
|| exit
date > .timestamp-init

- name: Prepare ccache
# Based on https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#example-using-the-cache-action example
id: cache-ccache
uses: actions/cache@v4
env:
compiler: 'CC=gcc CXX=g++'
cache-name: cache-ccache-${{ env.compiler }}
with:
path: |
~/.ccache
~/.cache/ccache
~/.config/ccache/ccache.conf
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/.timestamp-init') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-

- name: CCache stats before build
run: |
ccache -sv || ccache -s || echo "FAILED to read ccache info, oh well"
rm -f .timestamp-init

#- name: Debug gitlog2version processing
# run: bash -x ./tools/gitlog2version.sh || true

- name: WMNut CI Build Configuration
env:
compiler: 'CC=gcc CXX=g++'
run: |
PATH="/usr/lib/ccache:$PATH" ; export PATH
CCACHE_COMPRESS=true; export CCACHE_COMPRESS
ccache --version || true
( ${{env.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
./autogen.sh && \
./configure ${{env.compiler}} --enable-debug --enable-Werror

# NOTE: In this scenario we do not build actually WMNut in the main
# checkout directory, at least not explicitly (recipe may generate
# some files like man pages to fulfill the "dist" requirements;
# for now this may generate some libs to figure out their IDs).
# We do `make docs` to provide them as a separate tarball just
# in case, later.
# DO NOT `make dist-files` here as it includes `dist-sig` and
# needs a GPG keychain with maintainers' secrets deployed locally.
- name: WMNut CI Build to create "dist" tarball and related files
env:
compiler: 'CC=gcc CXX=g++'
run: |
PATH="/usr/lib/ccache:$PATH" ; export PATH
CCACHE_COMPRESS=true; export CCACHE_COMPRESS
ccache --version || true
( ${{env.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
make -s -j 8 dist dist-hash

- name: WMNut CI Build to verify "dist" tarball build
env:
compiler: 'CC=gcc CXX=g++'
run: |
PATH="/usr/lib/ccache:$PATH" ; export PATH
CCACHE_COMPRESS=true; export CCACHE_COMPRESS
ccache --version || true
( ${{env.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
make -s -j 8 distcheck

- name: WMNut CI Build to verify "dist" tarball build self-reproducibility
env:
compiler: 'CC=gcc CXX=g++'
run: |
PATH="/usr/lib/ccache:$PATH" ; export PATH
CCACHE_COMPRESS=true; export CCACHE_COMPRESS
ccache --version || true
( ${{env.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
make -s -j 8 distcheck-completeness

- name: CCache stats after distcheck
run: ccache -sv || ccache -s || echo "FAILED to read ccache info, oh well"

# Inspired by https://javahelps.com/manage-github-artifact-storage-quota
# Note that the code below wipes everything matched by the filter!
# We may want another script block (after this cleanup of obsolete data)
# to iterate clearing the way build by build until there's X MB available
# (at least 300KB as of Nov 2025).
- if: env.GITHUB_REF_TYPE != 'tag' && steps.subst-github-ref-name.outputs.result != 'master'
name: Delete Old Artifacts for this feature branch/PR
uses: actions/github-script@v6
id: delete_old_artifact_for_pr
continue-on-error: true
with:
script: |
const res = await github.rest.actions.listArtifactsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
})

res.data.artifacts
.filter(({ name }) => name === 'WMNUT-tarballs-${{ steps.subst-github-ref-name.outputs.result }}')
.forEach(({ id }) => {
github.rest.actions.deleteArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: id,
})
})

- name: Upload tarball and its checksum artifacts
uses: actions/upload-artifact@v4
id: upload_artifact
with:
name: WMNUT-tarballs-${{ steps.subst-github-ref-name.outputs.result }}
path: |
wmnut-*.tar*
compression-level: 0
overwrite: true

# NOTE: Despite the docs examples, due to GH API changes in Mar 2025
# this action can no longer update an existing check, only create a
# new one. Also calls authenticated with "github-actions" GH App may
# not set "details_url" freely...
# https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28
- name: "GHA-01: Create new GH Check report - shell/cURL"
if: always()
continue-on-error: true
env:
artifact_name: "WMNUT-tarballs-${{ steps.subst-github-ref-name.outputs.result }}.zip"
artifact_url: ${{ steps.upload_artifact.outputs.artifact-url }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ env.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/check-runs \
-d '{"head_sha": "${{ env.ref }}", "name": "URL for ${{ env.artifact_name }}", "details_url": "${{ env.artifact_url }}", "status": "completed", "conclusion": "${{ job.status }}", "output": {"title": "${{ env.artifact_url }}", "summary": "Dist and Docs [${{ env.artifact_name }}](${{ env.artifact_url }}) are available for commit ${{ env.ref }}"} }'
41 changes: 29 additions & 12 deletions .github/workflows/codeql.yml → .github/workflows/05-codeql.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# The contents below are based on sample configuration from CodeQL
# and on the variant of that file used in the main NUT repository.
#
name: "CodeQL"
name: "GHA-05: CodeQL"

on:
push:
Expand Down Expand Up @@ -34,13 +34,16 @@ jobs:
# Build with OS-provided NUT package (or build v2.8.0 if pkg is too old), or NUT trunk?
os: [ 'ubuntu-latest' ]
# TOTHINK: windows-latest, macos-latest?
build-mode: [ 'none' ]
build-mode: [ 'manual' ]
# https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
# Abusing "none" here to try building with ccache (and
# Abusing "manual" here to try building with ccache (and
# have codeql not intercept that build but parse C/C++
# files on its own), and "manual" to custom-build without;
# the "autobuild" mode is handled by codeql itself but
# would probably ignore our CC/CXX setting
# NOTE: We do not add ccache to PATH when actually compiling NUT code
# (we only speed up "configure" stages), so compilation always happens
# and is parsed by current CodeQL detectors of the day as they evolve!
compiler: [ 'CC=gcc CXX=g++', 'CC=clang CXX=clang++' ]

steps:
Expand All @@ -49,13 +52,13 @@ jobs:

# Using hints from https://askubuntu.com/questions/272248/processing-triggers-for-man-db
- if: matrix.language == 'cpp' && matrix.os == 'ubuntu-latest'
name: Initialize dependencies (Ubuntu)
name: NUT CI Prerequisite packages (Ubuntu)
run: |
echo "set man-db/auto-update false" | sudo debconf-communicate
sudo dpkg-reconfigure man-db
sudo apt-get update
sudo apt update
case x"${{matrix.compiler}}" in x*clang*) sudo apt install clang ;; x*) sudo apt install gcc g++ ;; esac
sudo apt-get install libxpm-dev libxext-dev libupsclient-dev libc6-dev-amd64-cross libgcc-s1-amd64-cross ccache
sudo apt install libxpm-dev libxext-dev libupsclient-dev libc6-dev-amd64-cross libgcc-s1-amd64-cross ccache
date > .timestamp-init

- name: Prepare ccache
Expand Down Expand Up @@ -122,9 +125,15 @@ jobs:
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the (whole) list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
queries: +security-extended,security-and-quality

# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
- if: matrix.build-mode == 'autobuild'
name: Autobuild
Expand All @@ -134,21 +143,29 @@ jobs:
CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: false

- if: matrix.build-mode != 'autobuild' && matrix.language == 'cpp'
name: WMNut CI Build
name: WMNut CI Build Configuration
run: |
case x"${{matrix.build-mode}}" in
xnone)
xmanual)
PATH="/usr/lib/ccache:$PATH" ; export PATH
CCACHE_COMPRESS=true; export CCACHE_COMPRESS
ccache --version || true
;;
xmanual|*)
echo "NOTE: NOT USING CCACHE for the CI-tested code base" >&2
xnone|*)
echo "NOTE: NOT USING CCACHE for the CI-tested code base configuration" >&2
;;
esac
( ${{matrix.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
./autogen.sh
./autogen.sh && \
./configure ${{matrix.compiler}} --enable-debug --enable-Werror

# NOTE: We do not add ccache to PATH here, so compilation always happens
# and is parsed by current CodeQL detectors of the day as they evolve:
- if: matrix.build-mode != 'autobuild' && matrix.language == 'cpp'
name: WMNut CI Build Compilation
run: |
echo "NOTE: NOT USING CCACHE for the CI-tested code base compilation" >&2
( ${{matrix.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
make -s -j 8 || exit

- if: matrix.build-mode != 'autobuild' && matrix.language == 'cpp'
Expand Down
Loading
Loading