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
6 changes: 2 additions & 4 deletions .github/actions/load-ci-image/action.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name: 'Load note-c CI Docker image'
description: 'Download the note-c CI Docker image artifact and load it into the local Docker engine'
runs:
using: 'composite'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Download image artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: note_c_ci_image
path: /tmp
Expand Down
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directories:
- "/"
- "/.github/actions/*"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
commit-message:
prefix: "chore(actions)"
groups:
actions-minor-patch:
update-types:
- "minor"
- "patch"
125 changes: 73 additions & 52 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,92 +8,101 @@ on:
workflow_dispatch:
inputs:
force_build:
description: 'Force rebuild and publish Docker image (even if Dockerfile unchanged)'
description: 'Force rebuild of the Docker image (even if Dockerfile unchanged); only published when run on master'
required: false
type: boolean
default: false

permissions:
contents: read

# Master runs get a per-SHA group so a newer push can't cancel a pending one.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}${{ github.ref == 'refs/heads/master' && format('-{0}', github.sha) || '' }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

jobs:
check_dockerfile_changed:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
outputs:
changed: ${{ steps.filter.outputs.changed }}

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

# TODO: This is a 3rd party GitHub action from some dude. Ideally, we'd
# use something more "official".
- name: Check if Dockerfile changed
uses: dorny/paths-filter@v2
uses: dorny/paths-filter@v4
id: filter
with:
base: 'master'
filters: |
changed:
- '.devcontainer/ci/Dockerfile'

build_ci_docker_image:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 30
needs: [check_dockerfile_changed]
if: ${{ needs.check_dockerfile_changed.outputs.changed == 'true' || inputs.force_build == true }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
uses: actions/checkout@v7

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v4

- name: Rebuild image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v7
with:
context: .
file: .devcontainer/ci/Dockerfile
load: true
tags: ghcr.io/blues/note_c_ci:latest
outputs: type=docker,dest=/tmp/note_c_ci_image.tar

- name: Upload image artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: note_c_ci_image
path: /tmp/note_c_ci_image.tar
retention-days: 7

check_architecture_docs:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 5

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Check architecture docs do not reference removed JSON map
run: |
architecture_json_pattern='architecture[.]''json'
embed_script_pattern='embed-architecture''-json'
for pattern in "$architecture_json_pattern" "$embed_script_pattern"; do
! grep -R "$pattern" \
rc=0
grep -R "$pattern" \
AGENTS.md ARCHITECTURE.md CLAUDE.md GEMINI.md \
.github/copilot-instructions.md .cursor/rules/architecture-docs.mdc \
docs
docs || rc=$?
[ "$rc" -eq 1 ] || exit 1
done

build_docs:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 10
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -106,13 +115,14 @@ jobs:
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/build_docs.sh ghcr.io/blues/note_c_ci:latest

check_libc_dependencies:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 10
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -125,11 +135,12 @@ jobs:
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/check_libc_dependencies.sh ghcr.io/blues/note_c_ci:latest

run_integration_tests:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 10

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Configure add_subdirectory integration test
run: cmake -S test/integration -B build-integration
Expand All @@ -141,13 +152,14 @@ jobs:
run: ctest --test-dir build-integration --output-on-failure

run_unit_tests:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 20
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -167,19 +179,21 @@ jobs:
run: sudo sed -i 's/\/note-c\///g' ./build/test/coverage/lcov.info

- name: Publish test coverage
uses: coverallsapp/github-action@master
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./build/test/coverage/lcov.info
file: ./build/test/coverage/lcov.info
format: lcov

run_low_mem_unit_tests:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 20
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -192,13 +206,14 @@ jobs:
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/run_unit_tests.sh ghcr.io/blues/note_c_ci:latest --mem-check --low-mem --single-precision

run_astyle:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 10
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -211,13 +226,14 @@ jobs:
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/run_astyle.sh ghcr.io/blues/note_c_ci:latest

run_cppcheck:
runs-on: ubuntu-latest
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 10
if: ${{ !cancelled() && (needs.build_ci_docker_image.result == 'success' || needs.build_ci_docker_image.result == 'skipped') }}
needs: [build_ci_docker_image]

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Load CI Docker image
# Only load the Docker image artifact if build_ci_docker_image actually
Expand All @@ -234,10 +250,11 @@ jobs:
# comparisons in n_cjson.c / n_ftoa.c use explicit (JNUMBER) casts so
# AppleClang -Wimplicit-const-int-float-conversion does not fail -Werror.
runs-on: macos-latest
timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Configure
run: cmake -B build -DNOTE_C_BUILD_TESTS=ON
Expand All @@ -257,21 +274,25 @@ jobs:
# or using a different mocking approach on macOS.

publish_ci_image:
runs-on: ubuntu-latest
# Make sure unit tests unit tests passed before publishing.
needs: [build_ci_docker_image, run_unit_tests]
# Only publish the image if this is a push event (or manual trigger with force_build) and the Docker image was rebuilt
if: ${{ (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.force_build == true)) && needs.build_ci_docker_image.result == 'success' }}
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: read
packages: write
# Make sure every job that uses the image passed before publishing.
needs: [build_ci_docker_image, build_docs, check_libc_dependencies, run_unit_tests, run_low_mem_unit_tests, run_astyle, run_cppcheck]
# Only publish from master, on a push (or manual trigger with force_build), and only if the Docker image was rebuilt.
if: ${{ github.ref == 'refs/heads/master' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.force_build == true)) && needs.build_ci_docker_image.result == 'success' }}

steps:
- name: Download image artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: note_c_ci_image
path: /tmp

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
21 changes: 15 additions & 6 deletions .github/workflows/md5srv-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,46 @@ on:
workflow_dispatch:
workflow_call: # reusable workflow

permissions:
contents: read

jobs:
test-md5srv: # job id
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 10
defaults:
run:
shell: bash
env:
TERM: xterm-256color
MD5SRV_TIMEOUT: 5
MD5SRV_DIR: ./test/hitl/scripts
BATS_VERSION: 1.10.0
steps:
- name: Setup Bats and bats libs
id: setup-bats
uses: bats-core/bats-action@3.0.0
uses: bats-core/bats-action@4.0.0
with:
bats-install: true
bats-version: 1.14.0
# Outside $HOME the libraries' cache can't be restored without root.
support-path: ${{ runner.temp }}/bats-support
assert-path: ${{ runner.temp }}/bats-assert
file-install: false
detik-install: false
github-token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Run Tests
id: run-tests
env:
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
run: |
cd ${{env.MD5SRV_DIR}}
bats -p --print-output-on-failure .
- name: Re-run Tests
if: failure()
if: failure() && steps.run-tests.outcome == 'failure'
env:
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
run: |
cd ${{env.MD5SRV_DIR}}
$HOME/.local/bin/bats -p --print-output-on-failure -x .
bats -p --print-output-on-failure -x .
Loading
Loading